Peter's Blog

Redefining the Impossible

Items filed under gotcha


Found another ruby gotcha when calling methods declared with default argument values:

irb(main):004:0> def a( b=1,c=2,d=3)
irb(main):005:1> print "#{b} #{c} #{d}\n"
irb(main):006:1> end
=> nil
irb(main):007:0> a(c=23)
23 2 3
=> nil

A python programmer would have expected this to print

2 23 3

as when calling the function we are saying we want c to be 23 and the other arguments to be left at their default values. Ruby appears to be ignoring the 'c=' bit when the function is being called so the first argument 'b' gets the value 23.

Pity, this python trick simplifies calling functions with lots of default parameters: you don't have to get the order of the parameters right or specify the correct default values of arguments before the one you are having to specify a value for. I should be calling this with:

irb(main):007:0> a(b=1, c=23)

i.e passing 'b=1' even though the declaration should tell ruby what the default for that should be. The 'b=' and 'c=' are only serving to help me selfdocument my code.

Ruby's behaviour is C/C++ish i.e. primitive.

UPDATE:

O'Reilly Ruby Cookbook:

   1  def fun_with_text(text, args={})
   2    text = text.upcase if args[:upcase]
   3    text = text.downcase if args[:downcase]
   4    if args[:find] and args[:replace]
   5      text = text.gsub(args[:find], args[:replace])
   6    end
   7    text = text.slice(0, args[:truncate_at]) if args[:truncate_at]
   8    return text
   9  end
  10  
  11  fun_with_text("Foobar", {:upcase => true, :truncate_at => 5})
  12  # => "FOOBA"
  13  fun_with_text("Foobar", :upcase => true, :truncate_at => 5)
  14  # => "FOOBA"
  15  fun_with_text("Foobar", :find => /(o+)/, :replace => '\1d', :downcase => true)
  16  # => "foodbar"

Filed under: gotcha noob ruby

2 Comments