我是 Ruby 新手,我想知道最好的做事方式是什么。
假设以下场景:
我有一个文本字段,用户可以在其中输入字符串。根据用户输入的内容(验证后),我想访问实例变量的不同字段。
示例:@zoo是一个实例变量。用户输入"monkey",我想访问@zoo.monkey. 我怎样才能在 Ruby 中做到这一点?
我想到的一个想法是有一个哈希:
zoo_hash = { "monkey" => @zoo.monkey, ... }
但我想知道是否有更好的方法来做到这一点?
谢谢!
我是 Ruby 新手,我想知道最好的做事方式是什么。
假设以下场景:
我有一个文本字段,用户可以在其中输入字符串。根据用户输入的内容(验证后),我想访问实例变量的不同字段。
示例:@zoo是一个实例变量。用户输入"monkey",我想访问@zoo.monkey. 我怎样才能在 Ruby 中做到这一点?
我想到的一个想法是有一个哈希:
zoo_hash = { "monkey" => @zoo.monkey, ... }
但我想知道是否有更好的方法来做到这一点?
谢谢!
在您的控制器中,您可以使用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
@zoo.attributes为您提供对象属性的散列。所以你可以像访问它们一样
@zoo.attributes['monkey']
nil如果该属性不存在,这将给出。调用不存在的方法会抛出NoMethodError
有更好的方法来做到这一点 - 你应该使用 Object#send 或(甚至更好,因为如果你尝试调用私有或受保护的方法会引发错误)Object#public_send,如下所示:
message = 'monkey'
@zoo.public_send( message )
您可以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'