开发者

In Ruby, how can you invoke a method using its default argument or with a specified argument without repeating code?

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 wit开发者_如何学编程hout 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


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


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

blah( *[a].compact )


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.


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.


I was looking for the same. (I think it is almost a bug in Ruby specs) I think I will solve this in other way ussing the option hash.

def foo(options={})
  bar = options.delete(:bar) || :default
  puts bar
end

foo 
#=> default

foo :bar => :something
#=> something

a = nil
foo :bar => a
#=> default

It is more extensible and is readable for any rubyst.


I vote for

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

too.

But if you would like to distinguish between the nil-value and no-argument situations, I suggest using a block like so:

def blah
    foo = block_given? ? yield : 17
end

blah         #=> 17
blah { nil } #=> nil
blah { 71 }  #=> 71
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜