I am learning Ruby basic, and trying to do some tests. I encounter an issue to understand the class method accesss scope.
Here is my code.
class User
attr_accessor :name
def initialize(name)
@name = name
@login_status = false
end
def login
puts "user #{name} logged in"
self.login_status = true
end
def logout
puts "user #{name} logged out"
self.login_status = false
end
def login?
self.login_status
end
private
attr_accessor :login_status
end
I got 'no such method error' when I had a test in irb
2.5.9 :001 > load 'user.rb'
=> true
2.5.9 :002 > u = User.new 'Mike'
=> #<User:0x00007ff1a10eb358 @name="Mike", @login_status=false>
2.5.9 :003 > u.login
user Mike logged in
=> true
2.5.9 :004 > u.login?
Traceback (most recent call last):
3: from /Users/sgao/.rvm/rubies/ruby-2.5.9/bin/irb:11:in `<main>'
2: from (irb):3
1: from user.rb:21:in `login?'
NoMethodError (private method `login_status' called for #<User:0x00007ff22f860938 @name="test", @login_status=false>)
2.5.9 :005 >
I am thinking why self.login_status = true works when I invoke u.login, but self.login_status fails when I invoke u.login?.
For the exact reason that
u.loginworks butu.fobnicatefoobarbazquxdoesn't: one method is defined, the other isn't.The method
User#login_status=is defined (attr_writer :login_statusdoes that for you), butUser#login_statusisn't. You need to define it.Module#attr_writeressentially looks more or less like this: