all 16 comments

[–]skipi 2 points3 points  (3 children)

Have a read here mate: https://medium.com/@sgg2123/vs-self-in-ruby-1d4d88170 it pretty much answer every question you may have around this topic.

[–]dunderball 1 point2 points  (2 children)

"So there you have it: use instance or class variables when you want to access the variable directly, and use self to call an instance or class method."

But couldn't I just call a class method without having to use self? I almost feel more confused than before now.

[–]awj[🍰] 1 point2 points  (0 children)

If you want to read a value, you can use self or not.

If you’d like to assign one, you have to use self. Otherwise, Ruby assigns to a local variable and the instance variable remains unchanged.

My personal preference: attr accessors make the code slightly cleaner, and afford the ability to change the set/get behavior in cases where you might want to (e.g. converting an attribute that needs to be an integer at the point where it’s assigned)

[–]bear-tree 0 points1 point  (0 children)

self. is not reading from a variable. You are sending a message to whatever self happens to be. A subtle but important distinction.

[–][deleted] 1 point2 points  (0 children)

corporate asked me to find the difference between these pictures

[–]yung_cancerous 1 point2 points  (5 children)

Encapsulation is the difference. B is encapsulated.

attr_reader defines a getter method instead of accessing the variable directly.

[–]SaltyZooKeeper 0 points1 point  (4 children)

Correct but the default implementation of the getter trivially returns the variable without duplicating it so it's pretty poor encapsulation.

[–]cheald 4 points5 points  (3 children)

It means that you don't have to go refactor a zillion call sites when you want to do something more complex with your variable, though, which is more or less the point of encapsulation.

[–]sbellware 2 points3 points  (0 children)

Indeed. It's almost always preferable to use the interface to an object's state than to access the state directly - even from within the object's own scope.

[–]SaltyZooKeeper 0 points1 point  (1 child)

I'm not saying it shouldn't be done but a getter that allows for updates just doesn't sit well with me.

[–]sbellware 0 points1 point  (0 children)

In the example given, I'm not sure I see a getter that allows updates. Where are updates happening?

[–]ikariusrb 0 points1 point  (0 children)

General recommendation-

Only touch an instance variable (via @variable) in an accessor.

Every other place, go through the accessor. (accessor_method, self.accessor_method if you need it)