Can someone explain the difference between initializing "self" and having @variables when defining classes?
Here's an example
class Child < Parent
def initialize(self, stuff):
self.stuff = stuff
super()
end
end
So in this case, wouldn't I be able to replace self.stuff
with @stuff
? What's the difference? Also, the super()
just means whatever is in the Parent initialize method the Child should just inherit it right?
The keyword self in Ruby enables you to access to the current object — the object that is receiving the current message. The word self can be used in the definition of a class method to tell Ruby that the method is for the self, which is in this case the class.
self is a special variable that points to the object that "owns" the currently executing code. Ruby uses self everwhere: For instance variables: @myvar. For method and constant lookup. When defining methods, classes and modules.
Ruby Class Variables Class variables begin with @@ and must be initialized before they can be used in method definitions. Referencing an uninitialized class variable produces an error.
In general, no, self.stuff = stuff
and @stuff = stuff
are different. The former makes a method call to stuff=
on the object, whereas the latter directly sets an instance variable. The former invokes a method which may be public (unless specifically declared private in the class), whereas the latter is always setting a private instance variable.
Usually, they look the same because it is common to define attr_accessor :stuff
on classes. attr_accessor
is roughly equivalent to the following:
def stuff
@stuff
end
def stuff=(s)
@stuff = s
end
So in that case, they are functionally identical. However, it is possible to define the public interface to allow for different results and side-effects, which would make those two "assignments" clearly different:
def stuff
@stuff_called += 1 # Keeps track of how often this is called, a side effect
return @stuff
end
def stuff=(s)
if s.nil? # Validation, or other side effect. This is not triggered when setting the instance variable directly
raise "Argument should not be nil"
end
@stuff = s
end
You actually can't use self.stuff=
unless you specifically create an attr_writer
for modifying that value.
In fact, these are equivalent:
class Child
attr_writer :stuff
end
class Child
def stuff=(val)
@stuff = val
end
end
It is more common to use an attr_writer
if that is the functionality you want, rather than the explicit method. But you will often use an explicit method if you want to perform extra error checking or change the way the assignment works.
To your question of when to use @stuff =
and when to use self.stuff =
, I would use the former if you only have simple assignments and if your class is simple, and would move towards the latter if your requirements might become more complicated. There are many other reasons too, but it's more a matter of style than anything else.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With