3

我是 Ruby 新手,我想知道最好的做事方式是什么。

假设以下场景:

我有一个文本字段,用户可以在其中输入字符串。根据用户输入的内容(验证后),我想访问实例变量的不同字段。

示例:@zoo是一个实例变量。用户输入"monkey",我想访问@zoo.monkey. 我怎样才能在 Ruby 中做到这一点?

我想到的一个想法是有一个哈希:

zoo_hash = { "monkey" => @zoo.monkey, ... }

但我想知道是否有更好的方法来做到这一点?

谢谢!

4

4 回答 4

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
于 2013-06-05T07:59:36.313 回答
3

@zoo.attributes为您提供对象属性的散列。所以你可以像访问它们一样

@zoo.attributes['monkey']

nil如果该属性不存在,这将给出。调用不存在的方法会抛出NoMethodError

于 2013-06-05T08:26:20.190 回答
2

有更好的方法来做到这一点 - 你应该使用 Object#send 或(甚至更好,因为如果你尝试调用私有或受保护的方法会引发错误)Object#public_send,如下所示:

message = 'monkey'
@zoo.public_send( message )
于 2013-06-05T07:52:08.023 回答
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'
于 2013-06-05T13:29:47.193 回答