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 #=> {}