1

I am learning Ruby and have stumbled upon some code similar to the one below, which shows the difference between instance variables and class instance variables. I've tested it in my console and it works like described (outputs "John"). What I don't understand is how define_method accesses the @name instance variable without preceding name with a @? Does it have a special capability that allows it to do so?

class User
  attr_reader :name

  def self.name
    "User"
  end

  def initialize(name)
    @name = name
  end

  define_method(:output_name) do
    puts name
  end
end

user1 = User.new("John")
user1.output_name #=> “John”
wawa
  • 11
  • 4
  • `attr_reader :name` creates a getter for the `@name` instance variable e.g. `def name; @name; end` this is the method that is being called in `output_name` and has nothing to do with `define_method` in this case – engineersmnky Apr 28 '20 at 16:46

1 Answers1

2

It's about scope

  define_method(:output_name) do
    puts name
  end

The puts name part of this has instance scope.

Therefore it has access to instance methods such as the one generated by

attr_reader :name
max pleaner
  • 26,189
  • 9
  • 66
  • 118
  • `self.class.define_method` would define a class instance method on `Object` meaning almost object would now have this method. However `define_singleton_method` would apply this method in the eigenclass scope which I think is what you were looking for – engineersmnky Apr 29 '20 at 02:25
  • @engineersmnky yeah, good point, you're right. – max pleaner Apr 29 '20 at 16:15
  • This isn't really "about scope", it's about the OP misunderstanding the difference between `name` and `@name`. They think that `define_method` is somehow able to access `@name` without the `@`, which of course is not at all what is happening. – user229044 Apr 30 '20 at 00:09