Ruby’s eval, attr_accessor, attr_reader, and attr_writer; Rails has_many, has_one, belongs_to

Tushar Tuteja
4 min readJun 20, 2018

This is my first medium post and the only post right now :) , it covers a variety of topics needed to understand how attr_accessor in Ruby works or how has_many works in an Active Record association. I would recommend you to code alongside while following this post.

1 The eval Function
One of the most amazing functions that I find in Ruby Programming Language is the eval function. There is so much one can do with it.
eval takes a string as input and evaluates that string as code.

Eg. the follwing code.

I saved the above code and I ran it in my terminal

The above code is a basic Ruby REPL(Read Evaluate Print Loop) like `irb`. It can only evaluate a single line and forgets what was declared in the previous line. Still powerful enough for a 5 line 91 characters code.

2 Everything in Ruby is executed.

We all know ruby is a dynamically typed interpreted language and everything is executed in Ruby. This part is just to emphasise the fact that indeed everything is executed in Ruby.

Eg.

If I save and run the above code I get the following output.

Ruby started loading the Person class and encountered a puts statement, and it ran the put statement.
Let’s add a few more lines to our code.

Output:

We all know that we cannot access name and age of an instance of the Person class as they are private variables, and we need to define getters and setters for it.
One way is to define your own getter and setter, the other way is to use attr_accessor. We won’t be using any of it, just see the following code.

Output:

I added a class method `my_attr_reader`, used `self` keyword to do it. We’ll discuss `self` keyword in another blog. You just need to know that the `self` keyword here is used to describe a class method. The `self` keyword is a long blog post in itself.

As soon as I defined my_attr_reader, I called it with “name” argument, and it evaluated the following string as code. The following code is added to the class at runtime.
This is a very powerful tool and a lot of things are build over the similar concept. And hence we defined our own attr_reader method, you may do the same for attr_accessor and attr_writer methods, you may define your own.

After the class is defined and `name` is printed, now I want to print the age, and there is no getter method for the age.
I can call the my_attr_reader method at runtime to create the getter for `age`. Look at the following code and output.

Output:

Voila!!! It works, it works as we were able to change the Person class at runtime, and we added a getter after the person object was made. we’ll discuss openness of classes in Ruby in another post.

One thing to note is that we cannot call Ruby’s attr_accessor, and the likes of it from outside of the class, as it is a private method. `Person.attr_reader` would give you an exception.

3 Rails has_many, has_one, belongs_to

I think by now you guys would have figured out how has_many, has_one and belongs_to work.
It would be a good assignment for your guys to write your own has_many, has_one and belongs_to function.

Ping me if you have any doubts.

See you next week with some more random concepts, I’ll try to find some order in them.
You may comment a topic for my next blog post.

More where this came from

This story is published in Noteworthy, where thousands come every day to learn about the people & ideas shaping the products we love.

Follow our publication to see more stories featured by the Journal team.

--

--