简体   繁体   English

我可以在Ruby中通过字符串引用对象的属性吗?

[英]Can I refer to an object's attribute by string in Ruby?

If I have a ruby class called Node: 如果我有一个名为Node的Ruby类:

class Node
  attr_accessor :a, :b, :c
  attr_reader :key
  def initialize(key)
    @key = key
  end
  def [](letter)
    if letter == 'a'
      return self.a
    elsif letter == 'b'
      return self.b
    elsif letter == 'c'
      return self.c
    end
  end
end

How can I optimize def [](letter) so I won't have repetitive code? 如何优化def [](letter)这样我就不会有重复的代码? More specifically, how can I access an attribute of an object (that is a ruby symbol :a , :b , or :c ) by using a corresponding string? 更具体地说,如何通过使用相应的字符串访问对象的属性(即红宝石符号:a:b:c )?

You can use send , which invokes a method dynamically on the caller, in this case self : 您可以使用send ,它可以在调用方上动态调用方法,在本例中为self

class Node
  def [](key)
    key = key.to_sym
    send(key) if respond_to?(key)
  end
end

Note that we check that self has the appropriate method before calling it. 请注意,在调用self之前,我们先检查其是否具有适当的方法。 This avoids getting a NoMethodError and instead results in node_instance[:banana] returning nil , which is appropriate given the interface. 这避免了出现NoMethodError ,而是导致node_instance[:banana]返回nil ,这对于给定接口是合适的。

By the way, if this is the majority of the behavior of your Node class, you may simply want to use an OpenStruct: 顺便说一句,如果这是Node类的大多数行为,则您可能只想使用OpenStruct:

require 'ostruct'
node_instance = OpenStruct.new(a: 'Apple', b: 'Banana')
node_instance.a    #=> 'Apple'
node_instance['b'] #=> 'Banana'
node_instance.c = 'Chocolate'
node_instance[:c]  #=> 'Chocolate'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM