对于Ruby来说,我很新,所以很抱歉,如果这是一个明显的问题。Ruby结构中的命名参数
我想在实例化一个Struct时使用命名参数,即能够指定Struct中的哪些项获取什么值,其余的默认值为nil。
比如我想做的事:
Movie = Struct.new :title, :length, :rating
m = Movie.new :title => 'Some Movie', :rating => 'R'
这是行不通的。
于是我想出了以下内容:
class MyStruct < Struct
# Override the initialize to handle hashes of named parameters
def initialize *args
if (args.length == 1 and args.first.instance_of? Hash) then
args.first.each_pair do |k, v|
if members.include? k then
self[k] = v
end
end
else
super *args
end
end
end
Movie = MyStruct.new :title, :length, :rating
m = Movie.new :title => 'Some Movie', :rating => 'R'
这似乎工作得很好,但我不知道是否有这样做的更好的办法,或者如果我做得相当疯狂。如果任何人都可以验证/拆分这种方法,我将非常感激。
UPDATE
我在1.9.2最初跑了这一点,并能正常工作;在Ruby中的其他版本但已经尝试过(谢谢你,RVM),它的工作/不工作如下:
- 1.8.7:不工作
- 1.9.1:工作
- 1.9。 2:工作
- 的JRuby(设置为1.9.2运行):不工作
JRuby是我的一个问题,因为我想保持其与部署的目的兼容。
另一个UPDATE
在这个日益散漫的问题,我尝试用Ruby的各种版本和发现的Structs在1.9.x的店其成员符号,但在1.8.7和JRuby ,它们被存储为字符串,所以我更新的代码为以下(以中已经给出善意的建议):
class MyStruct < Struct
# Override the initialize to handle hashes of named parameters
def initialize *args
return super unless (args.length == 1 and args.first.instance_of? Hash)
args.first.each_pair do |k, v|
self[k] = v if members.map {|x| x.intern}.include? k
end
end
end
Movie = MyStruct.new :title, :length, :rating
m = Movie.new :title => 'Some Movie', :rating => 'R'
现在,这似乎对我已经试过了Ruby的所有口味的工作。
你的代码看起来很好,真的。 – 2011-03-23 21:19:54
我一直在寻找同样的东西 - 是否有一个标准的gem来做到这一点,并指定哪些参数是必需的? – 2013-02-22 17:49:52
https://github.com/chemica/solid-struct这样做,但不强制执行所需的参数。 – 2015-06-20 12:47:27