有没有一种简单的方法来列出已在Ruby类中设置的访问器/阅读器?
class Test
attr_reader :one, :two
def initialize
# Do something
end
def three
end
end
Test.new
=> [one,two]
Run Code Online (Sandbox Code Playgroud)
我真正想要做的是允许初始化接受具有任意数量属性的哈希,但只提交已经定义了读者的哈希.就像是:
def initialize(opts)
opts.delete_if{|opt,val| not the_list_of_readers.include?(opt)}.each do |opt,val|
eval("@#{opt} = \"#{val}\"")
end
end
Run Code Online (Sandbox Code Playgroud)
还有其他建议吗?
这是我使用的(我称之为idiom hash-init).
def initialize(object_attribute_hash = {})
object_attribute_hash.map { |(k, v)| send("#{k}=", v) }
end
Run Code Online (Sandbox Code Playgroud)
如果你使用的是Ruby 1.9,你可以做得更干净(发送允许私有方法):
def initialize(object_attribute_hash = {})
object_attribute_hash.map { |(k, v)| public_send("#{k}=", v) }
end
Run Code Online (Sandbox Code Playgroud)
如果您尝试分配给foo并且方法"foo ="不存在,这将引发NoMethodError.如果你想干净(指定存在作者的attrs)你应该做一个检查
def initialize(object_attribute_hash = {})
object_attribute_hash.map do |(k, v)|
writer_m = "#{k}="
send(writer_m, v) if respond_to?(writer_m) }
end
end
Run Code Online (Sandbox Code Playgroud)
然而,这可能会导致您向对象提供错误的键(例如从表单中)而不是大声失败而只是吞下它们的情况 - 前方的痛苦调试.所以在我的书中,NoMethodError是一个更好的选择(它表示合同违规).
如果你只想要一份所有作家的名单(没有办法为读者做到这一点),那你就做了
some_object.methods.grep(/\w=$/)
Run Code Online (Sandbox Code Playgroud)
这是"获取一个方法名称数组,并为条目字符后面的单个等号结束的条目grep".
如果你这样做
eval("@#{opt} = \"#{val}\"")
Run Code Online (Sandbox Code Playgroud)
和val来自网络表单 - 恭喜你,你刚刚为你的应用程序配备了一个开放的漏洞.
| 归档时间: |
|
| 查看次数: |
5343 次 |
| 最近记录: |