Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

K-Sato
K-Sato

Posted on • Edited on

     

Ruby Getters and Setters

Table of contents

  1. What is a getter method
  2. What is a setter method
  3. What are accessors?
  4. References

What is a getter method?

A getter method is a method thatgets a value of an instance variable.
Without a getter method, you can not retrieve a value of an instance variable outside the class the instance variable is instantiated from.

Here is an example.

classMoviedefinitialize(name)@name=nameendendobj1=Movie.new('Forrest Gump')pobj1.name#=> undefined method `name' for #<Movie:0x007fecd08cb288 @name="Forrest Gump"> (NoMethodError)
Enter fullscreen modeExit fullscreen mode

As you can see, the value ofobj1 (name) can not be retrieved outsideMovie class. if you try to retrive a value of an instance variable outside its class without a getter method, Ruby raisesNo Mothod Error.

Now, Let's see how to retrieve the value ofobj1 outsideMovie class with a getter method.
All you have to do here is to define agetter method namedname. Though the name of a getter method can be anything, it is common practice to name a getter method the instance variable’s name.

classMoviedefinitialize(name)@name=nameenddefname@nameendendobj1=Movie.new('Forrest Gump')pobj1.name#=> "Forrest Gump"
Enter fullscreen modeExit fullscreen mode

What is a setter method?

A setter is a method thatsets a value of an instance variable.
Without a setter method, you can not assign a value to an instance variable outside its class.
if you try to set a value of an instance variable outside its class, Ruby raisesNo Method Error just like it does when you try to retrieve a value of an instance variable outside its class without a getter method.

classMoviedefinitialize(name)@name=nameenddefname#getter method@nameendendobj1=Movie.new('Forrest Gump')pobj1.name#=> "Forrest Gump"obj1.name='Fight Club'#=> undefined method `name=' for #<Movie:0x007f9937053368 @name="Forrest Gump"> (NoMethodError)
Enter fullscreen modeExit fullscreen mode

Defining a setter method inside a class makes it possible to set a value of an instance variable outside the class.
You can define a setter method like the code below.

classMoviedefinitialize(name)@name=nameenddefname#getter method@nameenddefname=(name)#setter method@name=nameendendobj1=Movie.new('Forrest Gump')pobj1.name#=> "Forrest Gump"obj1.name='Fight Club'pobj1.name#=> "Fight Club"
Enter fullscreen modeExit fullscreen mode

By usingname=, you can now assign a new valueFight Club toobj1.

What are accessors?

Accessors are a way to create getter and setter methods without explicitly defining them in a class.
There are three types fo accessors in Ruby.

  • attr_reader automatically generates a getter method for each given attribute.
  • attr_writer automatically generates a setter method for each given attribute.
  • attr_accessor automatically generates a getter and setter method for each given attribute.

First, let's take a look atattr_reader!
As you can see in the code below,name andyear are retrieved outsideMovie class even though there is no getter method for either of them. This is becauseattr_reader generates a getter method for each given attribute.

classMovieattr_reader:name,:yeardefinitialize(name,year)@name=name@year=yearendendobj1=Movie.new('Forrest Gump',1994)pobj1.name#=> Forrest Gumppobj1.year#=> 1994
Enter fullscreen modeExit fullscreen mode

Second, let's see howattr_writer works!
As I mentioned above,attr_witer generates a setter method for each given attribute. Therefore you can assign new values toob1 without explicitly writing setter methods forname andyear!

classMovieattr_reader:name,:yearattr_writer:name,:yeardefinitialize(name,year)@name=name@year=yearendendobj1=Movie.new('Forrest Gump',1994)obj1.name='Fight Club'obj1.year=1999pobj1.name#=> "Fight Club"pobj1.year#=> 1999
Enter fullscreen modeExit fullscreen mode

Last but certainly not least,attr_accessor does whatattr_reader andattr_writer do with just one line of code! It will automatically generate a getter and setter mehod for each given attribute.

classMovieattr_accessor:name,:yeardefinitialize(name,year)@name=name@year=yearendendobj1=Movie.new('Forrest Gump',1994)obj1.name='Fight Club'obj1.year=1999pobj1.name#=> "Fight Club"pobj1.year#=> 1999
Enter fullscreen modeExit fullscreen mode

References

Ruby Getters and Setters
How getter/setter methods work in Ruby
What is attr_accessor in Ruby?
rubylearning.com

Top comments(11)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
phallstrom profile image
Philip Hallstrom
  • Location
    Olympia, WA
  • Joined
• Edited on• Edited

Another neat trick is you can mark these as private so you can use them internally without worrying about them leaking out by throwing aprivate into the class.

This can be useful if you don't like remembering when to use@year vsyear or perhaps you want to be prepared to abstract it later.

require"date"classMovieattr_accessor:name,:yearprivate:year,:year=definitialize(name,year)@name=name@year=yearenddefageDate.today.year-yearendendobj1=Movie.new("Forrest Gump",1994)obj1.year#=> NoMethodError: private method `year' called for #<Movie:....>obj1.year=2018#=> NoMethodError: private method `year=' called for #<Movie:....>obj1.age#=> 24
CollapseExpand
 
tadman profile image
Scott Tadman
/developer|entrepreneur/iAlways looking for new developer talent, even those with zero experience, as you never know who's got the potential to become a great developer.
  • Location
    Toronto
  • Work
    Founder/CTO at PostageApp
  • Joined

It seems odd to declare these asprivate since you can always refer to them by their@ name internally.

CollapseExpand
 
phallstrom profile image
Philip Hallstrom
  • Location
    Olympia, WA
  • Joined

It can be odd, but it can also be useful as it allows you to more easily override it later without having to go find/replace all instances of@year in your class.

Or, if a class inherits from it and needs to change howyear is generated it's easier it doesn't have to worry about parent class using@year.

If that makes sense.

Thread Thread
 
tadman profile image
Scott Tadman
/developer|entrepreneur/iAlways looking for new developer talent, even those with zero experience, as you never know who's got the potential to become a great developer.
  • Location
    Toronto
  • Work
    Founder/CTO at PostageApp
  • Joined

It just seems inconsistent to useyear andself.year = ... in the code where one's bare and the other's necessarily prefixed, instead of@year consistently. This plus the way that@year is by default "private".

One of the major goals of object-oriented design is to properly contain any changes like that, so replacing@year with something else is at least contained to the one file or scope.

Subclass concerns are valid, though in Ruby it's generally understood you need to play nice with your parent's properties and avoid really getting in there and wrecking around.

CollapseExpand
 
k_penguin_sato profile image
K-Sato
Software Engineer
• Edited on• Edited

Thanks for sharing !!

CollapseExpand
 
tadman profile image
Scott Tadman
/developer|entrepreneur/iAlways looking for new developer talent, even those with zero experience, as you never know who's got the potential to become a great developer.
  • Location
    Toronto
  • Work
    Founder/CTO at PostageApp
  • Joined
• Edited on• Edited

These are also called "accessors" (read) and "mutators" (write) in other languages, but the principle is the same. Useful terminology for those coming to Ruby from places where those terms are used instead.

Ruby's way of declaring them asx= type methods is fairly unique and makes for some extremely concise code since there's no need forgetX /setX pairs, it's justx andx=.

Another thing worth mentioning is if you have a "setter" orattr_writer you can't use that without prefixing it with some kind of object, evenself.

For example:

class Example  attr_accessor :test  def assign!    test = :assigned  endendexample = Example.newexample.assign!example.test# => nil

That's because in the codetest = :assigned creates avariable namedtest, it doesn't call thetest= method. To use those you must doself.test = :assigned inside the context of that method orexample.test = :assigned by using some kind of variable for reference.

This leads to a lot of confusion in places like ActiveRecord where assigning to the auto-generated attributes "doesn't work".

CollapseExpand
 
rosebl profile image
Rose Black
  • Joined

Thank you for the detailed explanation of getterDeath By AI and setter methods! It’s clear how crucial these methods are for accessing and modifying instance variables in Ruby.

CollapseExpand
 
nkroker profile image
Nikhil Kumar Tyagi
  • Location
    Indore, India
  • Education
    Bachelor of Computer Science and Engineering
  • Work
    Software Engineer
  • Joined

I have a question how to generate this getter dynamically, for example you get a string argument and you have to generate a setter method for it which sets an instance variable which gets triggered when someone assign a value to it

class Movie  def generate_accessors(name, value)    generate_setter(name, value)    generate_getter(name, value)  end  def generate_getter(name, value)    self.class.send(:define_method, name) do      value    end  end  def generate_setter(name, value)    # Here we need to generate that setter dynamically    # def name=(name, value) #setter method    #   instance_variable_set("@#{name}", value)    # end  endendobj1 = Movie.newobj1.generate_accessors('foo', 'bar')obj1.foo                         # ==> 'bar'obj1 .foo = 'something'  # ==> This should trigger that setter
Enter fullscreen modeExit fullscreen mode
CollapseExpand
 
sophia2005 profile image
Smith Sophia
  • Joined

Thanks for the detailed explanation of the getter, setter, and accessor methods in Ruby. This information is very helpful to understandMapquest Directions how to manage and access instance variables in a class efficiently.

CollapseExpand
 
k_penguin_sato profile image
K-Sato
Software Engineer

Thank you👍!

CollapseExpand
 
pauldupont1120 profile image
Paul Dupont
  • Joined

I sincerely appreciate it. I just want to let you know that the article is fantastic since this knowledge is truly helpful to mebluey

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Software Engineer
  • Work
    Software Engineer
  • Joined

More fromK-Sato

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp