Home > database >  Why Rails' attr_getter is actually redundant
Why Rails' attr_getter is actually redundant

Time:03-12

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 not def self.name, so it is not a class method.
  • The attr_accessor allows class 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.
  • Related