简体   繁体   中英

Ruby - How to use the method parameter as the name of the variable?

How would I use the parameter value as the instance variable name of an object?

This is the object

Class MyClass    
    def initialize(ex,ey)
      @myvar = ex
      @myothervar = ey
    end
end

I have the following method

def test(element)
  instanceofMyClass.element  #this obviously doesnt work
end

How can I have the test method return either myvar or myothervar value depending on the element parameter. I don't want to write an if condition though, I want to pass myvar or myother var via element to the object instance if possible.

def test(element)
  instanceofMyClass.send(element.to_sym)  
end

You'll get a missing method error if instanceofMyClass doesn't respond to element.

def test(element)
  instanceofmyclass.instance_variable_get element
end

test :@myvar # => ex
test :@myothervar # => ey

I like the simplicity of send() , though one bad thing with it is that it can be used to access privates. The issue is still remains solution below, but at least then it's explicitly specified, and reader can see which methods are to be forwarded. The first one just uses delegation, while the second one uses more dynamic way to define methods on the fly.

require 'forwardable'
class A
  extend Forwardable
  def_delegators :@myinstance, :foo, :bar

  class B
    def foo
      puts 'foo called'
    end

    def bar
      puts 'bar called'
    end

    def quux
      puts 'quux called'
    end

    def bif
      puts 'bif called'
    end
  end

  def initialize
    @myinstance = B.new
  end

  %i(quux bif).each do |meth| # note that only A#quux and A#bif are defined dynamically
    define_method meth do |*args_but_we_do_not_have_any|
      @myinstance.send(meth)
    end
  end
end

a = A.new

a.foo
a.bar

a.quux
a.bif

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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