0

So I have a class

class MyPerson
   attr_accessor :id, :first_name, :surname

   def initialize(&block)
      instance_eval &block if block_given?
   end
end

And I want to create this from another class which looks like this

class MyCallingClass
  def initialize
     @my_name_generator_object.my_surname = 'Smith'
     @my_first_name = 'Bob'
  end

  def make_my_person
     surname_temp = @my_name_generator_object.my_surname  
     first_name_temp = @my_first_name  
     my_person = MyPerson.new do
         self.surname = surname_temp
         self.first_name = first_name_temp
     end
  end
end

What's happening is that

  • if I try to pass @my_name_generator to MyPerson in the constructor, it is not nil at the point of instantiating MyPerson, but a value of nil is passed to the initialize method of MyPerson

  • if I try to pass @my_first_name into the constructor (as above) even though @my_first_name has a value, it is not passed into the initialize method of MyPerson.

  • if I set @my_name_generator_object.surname and @my_first_name to a temp variable (as in the code above) then it works as expected.

Why is this and is there anything I can do to pass the instance variables directly into the constructor? It just looks messy having to have temp variables to make the code work.

rozza
  • 927
  • 2
  • 11
  • 24
  • The instance variables are defined in a different scope. See https://stackoverflow.com/questions/15773552/ruby-class-instance-variable-vs-class-variable – max pleaner Feb 12 '18 at 20:13
  • So how would get them into the same scope (other than setting them to a new variable)? – rozza Feb 12 '18 at 20:23
  • You edited the question since I made that comment. Since you added them to `initialize` it looks like they're in the correct scope, so I'm not sure. – max pleaner Feb 12 '18 at 21:05
  • Aha, so if they're not in the initialize, why does that stop a method accessing them? (it may say in the link, but there was a lot there and a lot of it was about inheritance, which doesn't apply here - I don't think!!) – rozza Feb 12 '18 at 21:15
  • when you are inside `initialize` you are in "instance scope". When you are outside it you are in "class scope". "Instance variables" (with @ as prefix) can be used in either, but not _between_ one or the other. – max pleaner Feb 12 '18 at 21:58
  • but isn't the method make_my_person in instance scope as well...? – rozza Feb 12 '18 at 22:26
  • yes it is, but before you edited the questionn to use `def initialize` you were defining the instance variable into class scope. Even now the first line of your `def initialize` won't work because `@my_name_generator_object` is not defined at that point. – max pleaner Feb 12 '18 at 23:50

0 Answers0