So I'm just learning some new stuff in C# & Python. Turns out both lanuages support nested methods (C# sort of does).
Python:
def MyMethod():
print 'Hello from a method.'
def MyInnerMethod():
print 'Hello from a nested method.'
MyInnerMethod()
C# (using new features in .NET 3.5):*
static void Main()
{
Console.WriteLine("Hello from main.");
Func<int, int> NestedMethod =
(x) =>
{
Console.WriteLine("In nested method. Value of x is {0}.", x);
return x;
};
int result = NestedMethod(3);
}
So why are nested methods so important? What makes them useful?
**The C# code has not been tested. Feel free to edit if it doesn't compile.*
First, realize I cannot give you a complete list. If you were to ask "why are screwdrivers useful?", I would would talk about screws and paint can lids but would miss their value in termite inspection. When you ask, "Why are nested functions useful?", I can tell you about scoping, closures, and entry points.
First, nesting can be an alternative to classes. I recently wrote some rendering code that took a file name for specialized mark-up code and returned a bitmap. This naturally lead to functions named grab_markup_from_filename() and render_text_onto_image() and others. The cleanest organization was one entry point named generate_png_from_markup_filename(). The entry point did its job, using nested functions to accomplish its task. There was no need for a class, because there was no object with state. My alternative was to create a module with private methods hiding my helpers, but it would be messier.
def generate_png_from_markup_filename(filename):
def grab_markup_from_filename():
...
... # code that calls grab_markup_from_filename() to make the image
return image
Second, I use nesting for closures. The most common example is for creating decorators. The trick is that I return a reference to an inner function, so that inner function and the outer parameter value are not garbage collected.
def verify_admin(function_to_call):
def call_on_verify_admin(*args, **kwargs):
if is_admin(global.session.user):
return function_to_call(*args, **kwargs)
else:
throw Exception("Not Admin")
return call_on_verify_admin # the return value of verify_admin()
use it this way:
def update_price(item, price):
database.lookup(item).set_field('price', price)
update_price = verify_admin(update_price)
or, more concisely:
@verify_admin
def update_price(item, price):
database.lookup(item).set_field('price', price)
And yes, it should be hard to trace. Remember that "def" is just another statement.
So, here are two places nested classes are helpful. There are more. It is a tool.
Nested methods are useful because there are many cases where you want to pass behaviour around, rather than just data. In many instances, it is clearer and easier to follow, in addition to being easier and faster to write, to just define that behaviour in the body of your method, where you are going to use it.
In .NET, LINQ is a great example of this. Suppose you wanted to create a list where each value was double its value in the original list:
list.Select(i => i*2)
where i => i*2
is equivalent to:
Func<int,int> double = delegate(int x) { return x*2; }
This is much simpler and clearer than creating a separate function.
Further, the function you declare may not have meaning elsewhere (ie, outside the scope of your method). In C#, you can even reference to variables declared inside your method body -- which you cannot do with a non-nested function.
Of course, you can also abuse nested functions...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With