我可以这样定义的方法:
def test(id, *ary, hash_params)
# Do stuff here
end
但是这使得hash_params
参数强制性的。 这些不工作之一:
def t(id, *ary, hash_params=nil) # SyntaxError: unexpected '=', expecting ')'
def t(id, *ary, hash_params={}) # SyntaxError: unexpected '=', expecting ')'
有没有一种方法,使之选?
Answer 1:
你不能做到这一点。 你必须考虑关于Ruby如何能够确定哪些属于*ary
,什么属于可选的哈希值。 由于红宝石无法了解你的心思,上面的参数组合(图示+可选)是不可能为它在逻辑上解决。
你要么必须重新安排你的论点:
def test(id, h, *a)
在这种情况下, h
不会是可选的。 或者,然后手动编程它:
def test(id, *a)
h = a.last.is_a?(Hash) ? a.pop : nil
# ^^ Or whatever rule you see as appropriate to determine if h
# should be assigned a value or not.
Answer 2:
有通过使用阵列扩展这种支持中的ActiveSupport extract_options!
。
def test(*args)
opts = args.extract_options!
end
如果最后一个元素是一个散列,那么它会从数组弹出并返回它,否则它会返回一个空的哈希值,这在技术上是一样的,你想要什么(*args, opts={})
做的。
的ActiveSupport阵列#extract_options!
Answer 3:
除了卡斯佩斯回答 :
您可以使用飞溅参数和检查,如果最后一个参数是一个哈希值。 然后你把哈希作为设置。
一个代码示例:
def test(id, *ary )
if ary.last.is_a?(Hash)
hash_params = ary.pop
else
hash_params = {}
end
# Do stuff here
puts "#{id}:\t#{ary.inspect}\t#{hash_params.inspect}"
end
test(1, :a, :b )
test(2, :a, :b, :p1 => 1, :p2 => 2 )
test(3, :a, :p1 => 1, :p2 => 2 )
结果是:
1: [:a, :b] {}
2: [:a, :b] {:p1=>1, :p2=>2}
3: [:a] {:p1=>1, :p2=>2}
这将使问题,如果你的阵列参数应该包含在最后位置的哈希值。
test(5, :a, {:p1 => 1, :p2 => 2} )
test(6, :a, {:p1 => 1, :p2 => 2}, {} )
结果:
5: [:a] {:p1=>1, :p2=>2}
6: [:a, {:p1=>1, :p2=>2}] {}
Answer 4:
你可以(误)使用可选块在参数列表的末尾:
def test(id,*ary, &block)
if block_given?
opt_hash = block.call
p opt_hash
end
p id
p ary
end
test(1,2,3){{:a=>1,:b=>2}}
# output:
# {:a=>1, :b=>2} #Hurray!
# 1
# [2, 3]
Answer 5:
@Casper是正确的。 只有一个参数可以有图示操作。 参数会被分配给第1左到右非splatted参数。 其余的参数会被分配到图示参数。
你可以这样做,因为他建议。 你也可以这样做:
def test(id,h={},*a)
# do something with id
# if not h.empty? then do something with h end
# if not a.empty? then do something with a end
end
下面是一些样品IRB运行:
001 > def test (id, h={}, *a)
002?> puts id.inspect
003?> puts h.inspect
004?> puts a.inspect
005?> end
=> nil
006 > test(1,2,3,4)
1
2
[3, 4]
=> nil
007 > test(1,{"a"=>1,"b"=>2},3,4)
1
{"a"=>1, "b"=>2}
[3, 4]
=> nil
008 > test(1,nil,3,4)
1
nil
[3, 4]
=> nil
也许,我应该补充。 你可以有一个可选的参数作为最后一个参数,但它必须是一个块的/ proc。
例如:
def test(a,*b, &c)
puts a.inspect
puts b.inspect
c.call if not c.nil?
end
下面是一些示例电话:
006 > test(1,2,3)
1
[2, 3]
=> nil
007 > test(1,2,3) {puts "hello"}
1
[2, 3]
hello
=> nil
文章来源: How to define a method in ruby using splat and an optional hash at the same time? [duplicate]