views:

68

answers:

5

Say I have a ruby method:

def blah(foo=17)
   ...
end

In code I want to invoke blah with a specific argument "blah(a)" or invoke blah using its default argument "blah()" Is there any way to do that without specifying the method name twice? I'm trying to avoid:

if a.nil?
  blah()
else
  blah(a)
end

Because it makes the code look more complicated than it is. Best I can come up with (didn't test) is:

args=[]
args << a unless a.nil?
a.send :blah, args
+6  A: 

I just tried a few ways, and didn't find any, but if you find yourself doing this a lot, I wonder of the benefit of using a default parameter that way. Try this instead:

def blah(foo=nil)
  foo ||= 17
  puts foo
end

blah()
a = nil
blah(a)
a = 20
blah(a)

This will output:

17
17
20
Doug Neiner
+3  A: 

I don't like this answer, but I guess it works:

blah( *[a].compact )
FM
This might be my favorite just because it doesn't involve modifying the "callee" method to accommodate making the "caller" method cleaner.
Dan Sandberg
A: 

I vote for

def blah(foo = nil)
    foo ||= 17
end

too.

But if you would like to distinguish nil-value and no-argument situation, I suggest using block, like this:

def blah
    foo = block_given? ? yield : 17
end

blah         #=> 17
blah { nil } #=> nil
blah { 71 }  #=> 71
ib
A: 

In ruby everything has a return value. So if also has a return value. The following method works with any number of arguments. The * expands an array so the array elemnts are individual arguments.

blah(*
  if a.nil?
    []
  else
    [a]
  end
)

You don't have to indent it this way, but this looked like the indentation to make it clearest.

johannes
+2  A: 

It's hard to say without knowing what the actual problem being solved is, but I have a feeling something like this would work best:

blah(a || 17)

This statement seems to more clearly express its intent, without leaving the reader to lookup the definition of the blah function in order to work out what the default is.

Tobias Cohen