Reputation: 1230
If I have a ruby class called Node:
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? 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?
Upvotes: 0
Views: 88
Reputation: 80041
You can use send
, which invokes a method dynamically on the caller, in this case 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. This avoids getting a NoMethodError
and instead results in node_instance[:banana]
returning nil
, which is appropriate given the interface.
By the way, if this is the majority of the behavior of your Node
class, you may simply want to use an 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'
Upvotes: 2