get instance variable name from itself in ruby

后端 未结 4 1028
花落未央
花落未央 2021-01-13 11:43

I have an instance variable @foo and I want to write some code so that I get string \'foo\'

any hint?

相关标签:
4条回答
  • 2021-01-13 11:57

    You can call the method instance_variables to get the name of all instance variables of an object. Caution though that instance variables are only included in that list after they have been initialized.

    >> class A; attr_accessor :foo; end
    => nil
    >> a = A.new
    => #<A:0x103b310b0>
    >> a.instance_variables
    => []
    >> a.foo = 42
    => 42
    >> a.instance_variables
    => ["@foo"]
    
    0 讨论(0)
  • 2021-01-13 12:04

    If all you have is a reference to the object, you can't really do it cleanly.

    def foo
      bar @something
    end
    
    def bar(value)
      value # no clean way to know this is @something
    end
    

    The only hack I can think of is to loop through ALL instance variables on self, looking for matches. But its a very messy approach that's likely to be slow.

    def bar(value)
      instance_variables.each do |ivar_name|
        if instance_variable_get(ivar_name) == value
          return ivar_name.to_s.sub(/^@/, '') # change '@something' to 'something'
        end
      end
    
      # return nil if no match was found
      nil 
    end
    
    @something = 'abc123'
    bar @something # returns 'something'
    
    # But passing the same value, will return a value it's equal to as well
    bar 'abc123' # returns 'something'
    

    This works because instance_variables returns an array of symbols that are the names of instance variables.

    instance_variables
    #=> [:@something, :@whatever] 
    

    And instance_variable_get allows you to fetch the value by it's name.

    instance_variable_get :@something # note the @
    #=> 'abc123'
    

    Combine the two methods and you can get close to what you want.


    Just use it wisely. Before using a solution based on this, see if you can refactor things a way so that it's not necessary. Meta-programming is like a martial art. You should know how it works, but have the discipline to avoid using it whenever possible.

    0 讨论(0)
  • 2021-01-13 12:14

    In Ruby, you can only manipulate objects. Variables (including instance variables) aren't objects.

    Besides, what do you want your magic method to return in this case:

    foo = Object.new
    bar = foo
    @baz = bar
    @qux = bar
    
    magic_method(foo) # what should the return value be and how would it know?
    
    0 讨论(0)
  • 2021-01-13 12:19
    class Object
        def get_name
          line_number = caller[0].split(':')[1].to_i
          line_exectued = File.readlines( __FILE__)[line_number-1]
          line_exectued.match(/(\S+).get_name/)[1]
        end
    end
    
    inconceivable = true
    
    p inconceivable.get_name
    
    0 讨论(0)
提交回复
热议问题