Categories
Uncategorized

Named Parameters in Method Calls: Python Si, Ruby No

"Hello My Name Is" sticker In an earlier article, Default and Named Parameters in C# 4.0 / Sith Lord in Training, I wrote about how C# 4.0 – that’s the version coming out with the next release of Visual Studio, known as Visual Studio 2010 – is going to provide support for named parameters.

In that article, I also incorrectly stated that Ruby supported named parameters. Luckily, Jörg W Mittag spotted my mistake an corrected me in a comment. I’ve since corrected the article and thought I’d show you how I got it wrong in the first place.

Ruby and My Named Parameter Goof

I had a vague recollection of Ruby accepting named parameters. I figured I’d be empirical and fired up irb – the Ruby REPL shell – and put together a quick little method to see if the recollection was correct:

# Ruby 1.8.6
def test_named_params(first, second)
    puts "#{first}\n#{second}"
end

Once put together, I made some test calls to the method:

# irb session (Ruby 1.8.6) irb(main):> test_named_params("alpha", "beta") alpha beta

=> nil irb(main):> test_named_params(first = "alpha", second = "beta") alpha beta

=> nil

Seeing that the interpreter didn’t choke on that named parameter call, I thought to myself “Vague recollection confirmed, Ruby supports named parameters!” and wrote the blog article.

Had my brain actually been firing on all cylinders, I would’ve given the method a proper test by providing the named parameters out of the order in which they appear in the method signature. Here’s what I would’ve seen:

# irb session (Ruby 1.8.6)
irb(main):> test_named_params(second = "alpha", first = "beta")
alpha
beta

=> nil

Uh-oh. If named parameters worked, the first output line would be “beta” and the second would be “alpha”. Clearly something’s wrong with my recollection.

Let’s try some non-existent named parameters – say, ones involving current entertainemtn news headlines — just to see what happens:

# irb session (Ruby 1.8.6)
irb(main):> test_named_params(lindsay_lohan_dui = "alpha",
jim_cramer_smackdown = "beta")

alpha

beta

=> nil

Even with nonsensical named parameters, the method is still accepting the values in order. Why is that?

Just about everything in Ruby has a return value (which can be anything, including nil). You can see for yourself in irb – here’s a quick do-nothing method definition:

irb(main)> def doNothing
irb(main)> end
=> nil

As you can see. defining a method returns a value of nil.

As Jorg pointed out, Ruby assignment statements return a value: the value used in the assigment. Once again, for proof, I’ll use an example from an irb session. In the example below, assigning the string "alpha" to the variable first also returns the string "alpha":

# irb session (Ruby 1.8.6)
irb(main):> first = "alpha"
=> "alpha"

In the call to test_named_params, the Ruby interpreter was interpreting my “named parameters” as assignment statements. first = "alpha" evaluates to plain old "alpha", but so does second = "alpha" (and for that matter, so does lindsay_lohan_dui = "alpha"). Each assignment statement in my parameter list was evaluated, and then those values were passed to method in positional order.

Python Supports Named Parameters

After getting the comment from Jorg and correcting my article, I wondered why I thought Ruby supported named parameters. Then it hit me – it’s Python.

So I fired up the Python REPL and put together this quick little method:

# Python 3.0
def test_named_params(first, second):
    print("%s\n%s" % (first, second))

And this time, I decided to be a little more thorough in my testing:

# Python 3.0 REPL
>>> test_named_params("alpha", "beta")
alpha
beta

>>> test_named_params(first = "alpha", second = "beta")
alpha
beta

>>> test_named_params(second = "alpha", first = "beta")
beta
alpha

And some additional searching on the web confirmed that yes, Python method calling does in fact support named parameters.

So in conclusion, when it comes to named parameters, it’s Python si, Ruby no…and C# pronto.

Categories
Uncategorized

Default and Named Parameters in C# 4.0 / Sith Lord in Training

Round Trip

sith_lord_in_training Back when I was working for OpenCola (from January 2000 through January 2002), the start-up cofounded by Cory Doctorow, I was doing a lot of work using beta versions of C# to build prototype peer-to-peer applications that got demoed to some large companies, including Microsoft, who were kind enough to provide us with betas of Visual Studio .NET and Windows XP.

I graduated to the 1.0 version when it came out. Even during the year after I left OpenCola (or more accurately, got the boot), I continued to write applications in C#, from things like a sales app for people who were selling practice certification tests to a trivia game for a company that was pitching it to Maxim. I do manage to land some interesting jobs from time to time.

That changed on Bastille Day 2003, my first day as Tucows’ Technical Evangelist, or as the title originally read, “Technical Community Development Coordinator”. Tucows’ client base were people who wanted to resell things like domain names and email, and as such were largely hosting companies. This in turn meant that they were using languages that you might consider “webbier”: open source dynamically-typed languages like Perl, PHP, Python and Ruby. I did what I could to stay away from Perl, I’d coded in PHP and Python for work before, and I picked up Ruby along the way.

Feeling a bit restless, I left Tucows in late 2007 to do Ruby on Rails development at what turned out to be Toronto’s worst-run startup, possibly ever. After that, it was project management at b5media, where I used Ruby to implement some “housekeeping” scripts. Although I hit up Microsoft Evangelist David Crow for a copy of Visual Studio so I could try out XNA, I really didn’t pay too much attention to C#. I installed it on my machine, wrote a lazy “Hello, World” app – a single WinForm with a button that displayed a MessageBox with the word “poop” when you clicked it – and promptly forgot about it.

The situation changed when I got laid off in September and then got hired as a Developer Evangelist for “The Empire” in October. Suddenly, I’m back in a world with a three-versions-later Visual Studio and a two-and-a-bit-versions-later of C# and .NET. I’ve got the programming know-how and the language basics down cold; it’s the changes in the language and library – generics, LINQ and a bunch of 2- and 3-letter acronyms beginning with “W” – that keep catching me by surprise.

Luckily, management is cool with my first year being a “learning journey”. They’re really interested in how I mix my schmoozing and community-building skills with a love of technology and programming and don’t mind that my first year is a “learning journey”. They especially don’t mind if I share what I learn along the way, which is what this series of articles, Sith Lord in Training, is all about. As I learn more about C# and the .NET framework, both present versions and the upcoming 4.0 versions, I’ll write about them here.

Default Parameters in C# 4.0

Suppose that you’ve got a method that takes a single boolean argument. Here’s how the argument affects what the method does":

  • If the argument is anything other than true or if no argument is provided, the method performs its normal task.
  • If the argument is true, the method performs its task, plus some additional stuff.

Here’s the Ruby implementation:

# Ruby

def myMethod(doSomethingOptional = false)
    puts "Doing my regular thing."
    if doSomethingOptional
        puts "Doing the optional thing."
    end
end

doSomethingOptional is a parameter with a default value. If myMethod is called without any parameters, doSomethingOptional is given the default value of false.

Unfortunately, the current 3.0 version of C# doesn’t support parameter defaults. The way to emulate this behaviour is to use method overloading:

  • One method to handle cases where no parameter is given
  • Another method to handle cases where a parameter is given

Here’s the implementation in C# 3.0:

// C# 3.0

public void MyMethod()
{
    MyMethod(false);
}

public void MyMethod(bool doSomethingOptional)
{
   Console.WriteLine("Doing my regular thing.");
   if (doSomethingOptional)
   {
       Console.WriteLine("Doing the optional thing.");
   }
}

That’s a bit long-winded for something that should be pretty simple. Luckily, this has been fixed in C# 4.0:

// C# 4.0

public void MyMethod(bool doSomethingOptional = false)
{
   Console.WriteLine("Doing my regular thing.");
   if (doSomethingOptional)
   {
       Console.WriteLine("Doing the optional thing.");
   }
}

And with that, the long-winded (and unnecessary, at least to my mind) method overloading workaround vanishes. Yay!

Named Parameters in C# 4.0

Named parameters make the meaning of the parameters explicit, as long as the parameter names themselves are pretty meaningful. Contrast the following call:

drawCircle(100, 200, 200, "yellow")

with this, which is supported in Python:

drawCircle(radius = 100, x = 200, y = 200, color = "yellow")

C# 3.0 doesn’t support named parameters, but C# 4.0 does. Here’s how you’d call MyMethod in C# 4.0 using them:

myMethod(doSomethingOptional: true)

As for the Python drawCircle method in the example above. here’s how you’d call it in C# 4.0:

DrawCircle(radius: 100, x: 200, y: 200, color: "yellow")

If this syntax is giving you some deja vu, it might be because it’s reminding you of Objective-C, where the call would look something like this:

[someObject drawCircleWithRadius:100 x:200 y:200 color:"yellow"]

See the Video

If you’d like to see more about default and named parameters in C# 4.0, there’s a video on the Chanel 9 site that covers them quite extensively. Go check it out!