I am having a hard time understanding
attr_accessor in Ruby. Can someone explain this to me?
I am having a hard time understanding
Basically they fake publicly accessible data attributes, which Ruby doesn't have.
attr_accessor is just a method. (The link should provide more insight with how it works - look at the pairs of methods generated, and a tutorial should show you how to use it.)
The trick is that
The need for
Hope this clarifies some of the little details. Happy coding.
1 This isn't strictly true and there are some "techniques" around this, but there is no syntax support for "public instance variable" access.
is a shortcut for:
it is nothing more than a getter/setter for an object
It is just a method that defines getter and setter methods for instance variables. An example implementation would be:
So this code here:
is equivalent to this code:
You can write this sort of method yourself in Ruby:
Let's say you have a class
Obviously we never defined method
Aha, we can read the name, but that doesn't mean we can assign the name. Those are two different methods. The former is called reader and latter is called writer. We didn't create the writer yet so let's do that.
Awesome. Now we can write and read instance variable
Even this can get repetitive. When you want both reader and writer just use accessor!
Works the same way! And guess what: the instance variable
That's it. In order to understand how
I think part of what confuses new Rubyists/programmers (like myself) is:
"Why can't I just tell the instance it has any given attribute (e.g., name) and give that attribute a value all in one swoop?"
A little more generalized, but this is how it clicked for me:
We haven't defined Person as something that can have a name or any other attributes for that matter.
So if we then:
...and try to give them a name...
We get an error because, in Rubyland, a Person class of object is not something that is associated with or capable of having a "name" ... yet!
BUT we can use any of the given methods (see previous answers) as a way to say, "An instance of a Person class (
Again, hitting this question from a slightly different and more general angle, but I hope this helps the next instance of class Person who finds their way to this thread.
Simply put it will define a setter and getter for the class.
are equivalant to define a setter and getter for the class.
If you are familiar with OOP concept, You must familiar with getter and setter method. attr_accessor does the same in Ruby.
Getter and Setter in General Way
Getter and Setter method in Ruby
Defines a named attribute for this module, where the name is symbol.id2name, creating an instance variable (@name) and a corresponding access method to read it. Also creates a method called name= to set the attribute.
I faced this problem as well and wrote a somewhat lengthy answer to this question. There are some great answers on this already, but anyone looking for more clarification, I hope my answer can help
Initialize allows you to set data to an instance of an object upon creation of the instance rather than having to set them on a separate line in your code each time you create a new instance of the class.
In the code above we are setting the name “Denis” using the initialize method by passing Dennis through the parameter in Initialize. If we wanted to set the name without the initialize method we could do so like this:
In the code above, we set the name by calling on the attr_accessor setter method using person.name, rather than setting the values upon initialization of the object.
Both “methods” of doing this work, but initialize saves us time and lines of code.
This is the only job of initialize. You cannot call on initialize as a method. To actually get the values of an instance object you need to use getters and setters (attr_reader (get), attr_writer(set), and attr_accessor(both)). See below for more detail on those.
Getters, Setters (attr_reader, attr_writer, attr_accessor)
Getters, attr_reader: The entire purpose of a getter is to return the value of a particular instance variable. Visit the sample code below for a breakdown on this.
In the code above you are calling the methods “item_name” and “quantity” on the instance of Item “example”. The “puts example.item_name” and “example.quantity” will return (or “get”) the value for the parameters that were passed into the “example” and display them to the screen.
Luckily in Ruby there is an inherent method that allows us to write this code more succinctly; the attr_reader method. See the code below;
This syntax works exactly the same way, only it saves us six lines of code. Imagine if you had 5 more state attributable to the Item class? The code would get long quickly.
Setters, attr_writer: What crossed me up at first with setter methods is that in my eyes it seemed to perform an identical function to the initialize method. Below I explain the difference based on my understanding;
As stated before, the initialize method allows you to set the values for an instance of an object upon object creation.
But what if you wanted to set the values later, after the instance was created, or change them after they have been initialized? This would be a scenario where you would use a setter method. THAT IS THE DIFFERENCE. You don’t have to “set” a particular state when you are using the attr_writer method initially.
The code below is an example of using a setter method to declare the value item_name for this instance of the Item class. Notice that we continue to use the getter method attr_reader so that we can get the values and print them to the screen, just in case you want to test the code on your own.
The code below is an example of using attr_writer to once again shorten our code and save us time.
The code below is a reiteration of the initialize example above of where we are using initialize to set the objects value of item_name upon creation.
attr_accessor: Performs the functions of both attr_reader and attr_writer, saving you one more line of code.
Most of the above answers use code. There is no point me repeating what they say, so I'll try to explain the concept without code:
Outside parties cannot access internal CIA secrets
The meaning of read and write attributes:
Objects inside a class can easily access each other
Exact same thing with classes and your ability to access variables, properties and methods within them.
I hope that helps!
The main functionality of attr_accessor over the other ones is the capability of accessing data from other files.
Hope this helped!
Attributes and accessor methods
Attributes are class components that can be accessed from outside the object. They are known as properties in many other programming languages. Their values are accessible by using the "dot notation", as in object_name.attribute_name. Unlike Python and a few other languages, Ruby does not allow instance variables to be accessed directly from outside the object.
In the above example, c is an instance (object) of the Car class. We tried unsuccessfully to read the value of the wheels instance variable from outside the object. What happened is that Ruby attempted to call a method named wheels within the c object, but no such method was defined. In short, object_name.attribute_name tries to call a method named attribute_name within the object. To access the value of the wheels variable from the outside, we need to implement an instance method by that name, which will return the value of that variable when called. That's called an accessor method. In the general programming context, the usual way to access an instance variable from outside the object is to implement accessor methods, also known as getter and setter methods. A getter allows the value of a variable defined within a class to be read from the outside and a setter allows it to be written from the outside.
In the following example, we have added getter and setter methods to the Car class to access the wheels variable from outside the object. This is not the "Ruby way" of defining getters and setters; it serves only to illustrate what getter and setter methods do.
The above example works and similar code is commonly used to create getter and setter methods in other languages. However, Ruby provides a simpler way to do this: three built-in methods called attr_reader, attr_writer and attr_acessor. The attr_reader method makes an instance variable readable from the outside, attr_writer makes it writeable, and attr_acessor makes it readable and writeable.
The above example can be rewritten like this.
In the above example, the wheels attribute will be readable and writable from outside the object. If instead of attr_accessor, we used attr_reader, it would be read-only. If we used attr_writer, it would be write-only. Those three methods are not getters and setters in themselves but, when called, they create getter and setter methods for us. They are methods that dynamically (programmatically) generate other methods; that's called metaprogramming.
The first (longer) example, which does not employ Ruby's built-in methods, should only be used when additional code is required in the getter and setter methods. For instance, a setter method may need to validate data or do some calculation before assigning a value to an instance variable.
It is possible to access (read and write) instance variables from outside the object, by using the instance_variable_get and instance_variable_set built-in methods. However, this is rarely justifiable and usually a bad idea, as bypassing encapsulation tends to wreak all sorts of havoc.
Another way to understand it is to figure out what error code it eliminates by having
The following methods are available:
The following methods throws error:
To summarize an attribute accessor aka attr_accessor gives you two free methods.
Like in Java they get called getters and setters.
Many answers have shown good examples so I'm just going to be brief.
In the old ruby docs a hash tag # means a method. It could also include a class name prefix... MyClass#my_method
Hmmm. Lots of good answers. Here is my few cents on it.