0

Excuse me for the noob question.Please explain me outputs of the below ruby programme for implementing attr_accessor.

  class SimpleService

        attr_accessor :name

        def initialize(name)
          @name = name
        end

        def process
          if false # some condition met
            name = 'Akshay'
          end
          name
        end
      end

When I execute this class

      SimpleService.new('John Doe').process
      => nil

Why is the result nil?

when I use self explicitly to name

    def process
        if false # some condition met
          self.name = 'Akshay'
        end
        name
      end

Now the output is

    SimpleService.new('John Doe').process
    => "John Doe"

why is the result now "John Doe"?

I am a beginner in ruby.

Thanks in advance!

current_user
  • 1,172
  • 1
  • 16
  • 28
  • @jörg-w-mittag I disagree this is a duplicate. This question is more about why using the explicit receiver under `if false` changes the behavior of the returned value, that _does not require an exlicit receiver_ by any means. – Aleksei Matiushkin Sep 30 '17 at 12:04

1 Answers1

1

The thing is when you call name = you implicitly declare new local variable. Try this:

def process
  name = 'Akshay'
  puts local_variables.inspect
end

Why is it that way is a complicated question, discussed many times there and here. The setter always requires in explicit receiver. Period.

Once you have the line name = 'Akshay' inside a method, you introduce a new local variable and this method’s scope gets extended with new local variable name, despite how is was declared. It’s basically done by ruby parser.

And local variables take precedence over instance methods. That is why what is returned in the last line is a local variable. That was apparently not set, due to falsey condition above. Hence nil.

Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160