Did you know you can create additional scopes without specifying a keyword? Let me demonstrate this briefly:
// C#
public void MyFunction()
{
var x = 1;
{
var y = 2;
}
var z = 3;
}
x and z will both be in scope for anything below their declaration, but y will be lost as soon as the end curly brace is hit. I do see two uses for this in the real world, even if their scope of usefulness very slim.
1. If you have variables who's purpose is to initialize other variables.
This is probably getting pretty smelly about now, but there are certain situations where it's hard to eliminate the "in between" variables. In these cases, I would use an additional scope to make sure the intent of these variables is clear. Then when someone else reads the code, they can more easily abstract those variables in their mind. Here's an example:
// C#
public void UpdateOrderLine(Line newOrderLine)
{
Line originalLine;
{
var order = _context.Orders.Single(o => o.Id == newOrderLine.OrderId);
originalLine = order.Lines.Single(l => l.Id == newOrderLine.Id);
}
var transformedLine = TransformLine(newOrderLine, originalLine);
SubmitLine(transformedLine);
}
In the scope above, we don't want anything to touch the sales order, so we keep it in scope just long enough to grab the original line. It's a bit of a contrived example, but it still shows how you could use this in your program the couple of times this shows up.
2. When you have no function line limit.
There's a huge push against OOP right now. One of the things that comes along with this is being ok with longer (200+ line) functions. I don't personally subscribe to "longer functions are fine," but I do work in a code base with large functions. In these circumstances, it's still helpful to scope out operations. For instance, let's say that we have 3 business rules. We can wrap each business rule in a scope and put a comment at the top of the scope delineating why it's in a separate scope. I got the idea for this from the video Object Oriented Programming is Bad.
// C#
public List<string> ValidateOrder(Order order)
{
var errorList = new List<string>();
// grab the order rules (remember, this is just example code)
var orderRules = _context.OrderRules.Single(or => or.Id == order.OrderRulesId);
// Make sure we can identify the items being ordered.
{
var dbItems = _context.Items.Where(i => order.Items.Contains(i.Id);
var allItemsAreKnown = dbItems.Count() = order.Items.Count();
if (!allItemsAreKnown)
{
errorList.Add("We can't identify all of the items in the order.");
}
}
// Make sure minimum quantity is met.
{
var minimumQuantity = orderRules.MinimumQuantity;
var orderMeetsMinimumQuantity = order.Quantity > minimumQuantity;
if (!orderMeetsMimimumQuantity)
{
errorList.Add("Order does not meet minimum quantity.");
}
}
// Make sure the customer is valid
{
var customer = _context.Customer.FirstOrDefault(c => c.Id == order.CustomerId);
var customerIsValid = customer != null;
if (!customerIsValid)
{
errorList.Add("We can't recognize this customer");
}
}
return errorList;
}
Where to go from here
First, let me know if there are any other uses for this I've missed :).
Second, go watch the video about how Object Oriented Programming is Bad and then formulate your arguments for or against it. Personally, I agree that the OOP Brian is talking about is really bad. But I believe that this is what OOP has evolved into. It's not what OOP was intended to be.
Top comments (7)
Huh. I wouldn't see "longer functions are okay" as an anti-OOP thing. Functional programming thrives on even shorter, more contained functions than OOP. That said, function complexity has always been a difficult thing to wrap one's head around. Is a function bad because it is long, because it does too many things, or because it is poorly-structured? Blank scopes do, at least, solve the latter issue.
I wouldn't say Functional programming is an anti-OOP thing either :). But I think you're right, I may have generalized what I've heard in contexts.
I like the way you summarized these three problem areas for functions. That was very well stated.
You might want to use let or const keywords because var will bubble up to the function block since it's the only block var recognizes as a scope
This is not JavaScript 🤷♂️
The initial function declares a void return type which sure isn't a JavaScript thing
You're right! I just read the function body. I'll show myself out...
Haha 😁
You know, it's funny. I originally included JS examples as well but then wasn't sure 100% sure how scoping worked. I appreciate knowing now :)