I'm learning the actual functionality of Ruby on Rails' attr_accessor. In the example below, I know it will make both "name" and "name=" methods. Among them, I can test the actual effect of "name=", but even if I remove the entire line of attr_accessor, it does not affect me getting the parameter value of "name". In other words, attr_getter actually does nothing.
But this is theoretically wrong, how can I fix this wrong perception?
class HelloWorld
attr_accessor :name
def initialize(name = "Old name")
@name = name
end
def hello
puts "Hello, I am #{@name}"
end
def intro
puts "I name is #{@name}"
end
end
keaton = HelloWorld.new()
keaton.name = "New name"
keaton.hello #=> Hello, I am New name
keaton.intro #=> I name is New name
CodePudding user response:
As it was mentioned it the comments, it's not about Rails, it's a part of the Ruby core.
@name
is just an instance variable availbale only inside an instance of HelloWorld
. When you remove attr_accessor :name
you won't be able to read or write @name
from outside (actually you can by using instance_variable_get
and instance_variable_set
. But do you really need it?)
class HelloWorld
def initialize(name = "Old name")
@name = name
end
end
hello_world = HelloWorld.new
You can't read it
hello_world.name
undefined method `name' for #<HelloWorld:0x00007f3125ea51e8 @name="Old name"> (NoMethodError)
You can't write it
hello_world.name= 'New name'
undefined method `name=' for #<HelloWorld:0x00007f3125ea51e8 @name="Old name"> (NoMethodError)
It's up to you to decide do you need to give an access to a variable.
If you need only a reader use attr_reader
. If you want to write it use attr_writer
. If you need both, just leave it as it is now with attr_accessor
.
CodePudding user response:
Depends on you.
This is not theoretically wrong. Actually, we have the option of how to work program code. we use the OOP concept in the program code. This code of the program is logically correct.
I think you are saying this your code is correct.
class HelloWorld
def setName(name = "Old name")
@name = name
end
def hello
puts "Hello, I am #{@name}"
end
def intro
puts "I name is #{@name}"
end
end
keaton = HelloWorld.new()
keaton.setName("New name")
keaton.hello
keaton.intro
#OUTPUT :
#Hello, I am New name
#I name is New name
You know get & set method in a property in other languages. Get method returns the value of the variable and set is assigned a value to the name variable
For example.: In C#, get set method in a property
public class HelloWorld
{
private int _name;
public int Age
{
get { return _name; }
set { _name = value; }
}
}
same logic in ruby
class HelloWorld
attr_accessor :name
def initialize
@name = name
end
end
CodePudding user response:
I think I get it, to put it simply:
- The original getter and setter define instance methods "name and name=" respectively.
# getter
def name
@name
end
# setter
def name=(value)
@name = value
end
- That is,
def name
is notdef self.name
, so it is not a class method. - The
attr_accessor
allowsclass HelloWorld
and its new instance to use the instance method "name and name=". - The default value of the method "name and name=" is the specified instance variable @name of the initialize.
def initialize(name = "No name")
@name = name
end
- The methods "hello" and "intro" cannot be reassigned values (like a setter can do), but can have richer output results, such as sentences.