Cайт веб-разработчика, программиста Ruby on Rails ESV Corp. Екатеринбург, Москва, Санкт-Петербург, Новосибирск, Первоуральск

Админка на Ruby on Rails

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