Ruby 2.0.0 - именованые аргументы
Ruby 2.0.0 - использование именованых аргументов (keyword arguments).
# Ruby 1.9: # (From action_view/helpers/text_helper.rb) def cycle(first_value, *values) options = values.extract_options! name = options.fetch(:name, 'default') # ... end # Ruby 2.0: def cycle(first_value, *values, name: 'default') # ... end # CAUTION: Not exactly identical, as keywords are enforced: cycle('odd', 'even', nme: 'foo') # => ArgumentError: unknown keyword: nme # To get exact same result: def cycle(first_value, *values, name: 'default', **ignore_options) # ... end
Known bug: невозможно игнорировать дополнительные параметры без определения ** аргумента (указания его имени). Ошибка исправлена, но в ruby2.0.0-p0 пока без изменений. В релизе ruby2.0.0-p195 все уже работает как надо.
def wrap(string, before: "<", after: ">") # no need to retrieve options from a hash "#{before}#{string}#{after}" end # optional p wrap("foo") #=> "<foo>" # one or the other p wrap("foo", before: "#<") #=> "#<foo>" p wrap("foo", after: "]") #=> "<foo]" # order not important p wrap("foo", after: "]", before: "[") #=> "[foo]" # double splat to capture all keyword arguments, # or use as hash as keyword arguments def capture(**opts) opts end p capture(foo: "bar") #=> {:foo=>"bar"} # keys must be symbols opts = {:before => "(", :after => ")"} p wrap("foo", opts) #=> "(foo)" # the old hash style syantax is still accepted for keyword arguments p wrap("foo", :before => "{", :after => "}") #=> "{foo}"
Мои собственные тесты:
def test(a, b = nil, c: 'default-c', d: 'default-d', **ignore) print "a=#{a}, b=#{b}, c=#{c}, d=#{d}, ignore=#{ignore}\n" end def test1(a, c: 'default-c', d: 'default-d') end def test2(*opts) print "#{opts}\n" end def test3(**opts) print "#{opts}\n" end param = { :c => 'my-c', :d => 'my-d', :a => 'my-a' } test 'test', '444', '555' #=> wrong number of arguments (3 for 1..2) (ArgumentError) test1 'my_test1', param #=> unknown keyword: a (ArgumentError) test "my_test_first" #=> a=my_test_first, b=, c=default-c, d=default-d, ignore={} test 'my_test', param #=> a=my_test, b=, c=my-c, d=my-d, ignore={:a=>"my-a"} test 'my_test2', '222', param #=> a=my_test2, b=222, c=my-c, d=my-d, ignore={:a=>"my-a"} test 'my_test3', '333', :d => 'my-d', :a => 'my-a' #=> a=my_test3, b=333, c=default-c, d=my-d, ignore={:a=>"my-a"} test2 :a => 1, :b => 2, :c => 3 #=> [{:a=>1, :b=>2, :c=>3}] test3 :a => 1, :b => 2, :c => 3 #=> {:a=>1, :b=>2, :c=>3} test3 #=> {}