我是Ruby的新手,我想知道最好的做事方式是什么。
假设以下情形:
我有一个文本字段,用户可以在其中输入字符串。根据用户输入的内容(验证后),我想访问实例变量的不同字段。
示例:@zoo
是一个实例变量。用户输入"monkey"
,我想访问@zoo.monkey
。我怎么能在Ruby中做到这一点?
我想到的一个想法就是哈希:
zoo_hash = { "monkey" => @zoo.monkey, ... }
但我想知道是否有更好的方法来做到这一点?
谢谢!
答案 0 :(得分:3)
在您的控制器中,您可以使用public_send
(或甚至send
)方法,如下所示:
def your_action
@zoo.public_send(params[:your_field])
end
显然这是没有好,因为有人可以发布像delete_all
之类的方法作为方法名称,因此您必须清理从表单中获得的值。举个简单的例子:
ALLOWED_METHODS = [:monkey, :tiger]
def your_action
raise unless ALLOWED_METHODS.include?(params[:your_field])
@zoo.public_send(params[:your_field])
end
答案 1 :(得分:3)
@zoo.attributes
为您提供对象属性的哈希值。所以你可以像
@zoo.attributes['monkey']
如果该属性不存在,这将给nil
。调用不存在的方法将抛出NoMethodError
答案 2 :(得分:2)
有更好的方法可以做到这一点 - 你应该使用Object#send或(甚至更好,因为如果你尝试调用private或protected方法会引发错误)Object#public_send,就像这样:
message = 'monkey'
@zoo.public_send( message )
答案 3 :(得分:0)
您可以在班级中实施method_missing
并让其查询@zoo
以获取匹配方法。文档:http://ruby-doc.org/core-1.9.3/BasicObject.html#method-i-method_missing
require 'ostruct' # only necessary for my example
class ZooKeeper
def initialize
@zoo = OpenStruct.new(monkey: 'chimp')
end
def method_missing(method, *args)
if @zoo.respond_to?(method)
return @zoo.send(method)
else
super
end
end
end
keeper = ZooKeeper.new
keeper.monkey #=> "chimp"
keeper.lion #=> NoMethodError: undefined method `lion'