Instance Variable: Self VS @

Instance variable: self vs @

Writing @age directly accesses the instance variable @age. Writing self.age tells the object to send itself the message age, which will usually return the instance variable @age — but could do any number of other things depending on how the age method is implemented in a given subclass. For example, you might have a MiddleAgedSocialite class that always reports its age 10 years younger than it actually is. Or more practically, a PersistentPerson class might lazily read that data from a persistent store, cache all its persistent data in a hash.

ruby should I use self. or @

When you use @lines, you are accessing the instance variable itself. self.lines actually goes through the lines method of the class; likewise, self.lines = x goes through the lines= method. So use @ when you want to access the variable directly, and self. when you want to access via the method.

To directly answer your question, normally you want to set the instance variables directly in your initialize method, but it depends on your use-case.

Python self.variable vs private member instance variable

There is in fact a difference between those two variables:

Since __var_A is defined in class Foo instead of an individual member-function like __init__, you can change it for all instances at once like this:

Foo._Foo__var_A = 2

This will not work for __var_B since you define it individually per instance.

Note though, that changing __var_A on an instance will not change it for everyone else, it will instead put a local override into the object itself:

foo2 = Foo()
foo2._Foo__var_A = 1
Foo._Foo__var_A = 2
(foo2._Foo__var_A, foo._Foo__var_A) # Returns: (1, 2)

Understanding the self keyword when referring to a class instance variable in a ruby?

tl;dr: foo = value will always refer to a local variable foo not the method call self.foo=(value).


I am assumed this is because I need the self keyword to refer to the instance variable, total

No, total is a local variable, not an instance variable. @total is an instance variable. A local variable lives for the current scope, like a single method call. An instance variable sticks with the object.

You need the self keyword to refer to the method total=. Let's dive in.

attr_accessor :total declares two methods, total and total=. These are wrappers to get and set the instance variable @total. The following code does the equivalent.

def total
@total
end

def total=(value)
@total = value
end

Note that the method is named total=, this will become important in a moment.

With that in mind, let's look at your code.

def add(amount)
self.total = self.total + amount
end

(Almost) everything in Ruby is really a method call. The above is syntax sugar for calling the total= method on self.

def add(amount)
self.total=(self.total + amount)
end

Now what happens if we remove self like so?

def add(amount)
total = total + amount
end

In Ruby, self is optional. Ruby will figure out if total means the method total or the local variable total. The local variable takes precedence and assignment is always to a local variable.

total = total + amount works like so:

def add(amount)
total = self.total + amount
end

Assignment is always to a local variable.

To further illustrate, what if we declared total first?

def add(amount)
total = 23
self.total = total + amount
end

The existing local variable total takes precedence over the total() method. total + amount refers to the local variable total and so cr.add(10); puts cr.total will be 33.


total = ... will always refer to the local variable total. For this reason if you want to use method assignment you must explicitly use self.total=. In other cases you can drop the self. And avoid local variables with the same name as methods.

def add(amount)
# self.total = self.total + amount
self.total = total + amount
end

Why did I not need self in add_student?

Because there is no ambiguity. You're not assigning to a local variable roster.

def add_student(student, grade)
roster[grade] = roster[grade] || []
roster[grade] << student
end

roster[grade] is really self.roster.[]=(grade). You are calling self.roster which returns a Hash and then calling the []= method on that Hash to give it a new key/value pair.

Similarly, roster[grade] << student is self.roster.[](grade).<<(student). Get aHash, call [[]](https://ruby-doc.org/core/Hash.html#method-i-5B-5D) on it to retrieve theArrayand call [<<](https://ruby-doc.org/core/Array.html#method-i-3C-3C) on thatArray`.

def add_student(student, grade)
self.roster.[]=(grade) = self.roster.[](grade) || []
self.roster.[](grade).<<(student)
end

Yes, [], []=, and << are all methods names like any other.


A lot of Ruby mysteries go away once you understand the method calls under the syntax sugar and that things like [], []=, << and so on are method names.

Difference between using self.variable and _variable when init these variables

The difference is simple: Using self.label = [[UILabel alloc] init] will actually invoke the method [self setLabel:[[UILabel alloc] init]], and using _label = [[UILabel alloc] init] will directly assign the value to the instance variable.

In practice what this means is that using the dot syntax is usually the best as the method invoked probably handles a lot of stuff for you, including:

  • Memory management: For example, if you declare a property with attribute 'strong' or 'retain', then the method invoked should retain the object assigned.
  • Key-Value Coding notifications: Maybe the class is key-value coding compliant for the property, which means the invoked method will notify the changes to observer objects.

Why would you not use the dot syntax? There are two potential reasons:

  • To avoid side effects: A good practice is to not use the dot syntax inside an initializer method. This is because we want to assign the value but don't want the other side effects of the invoked method for safety reasons.
  • Performance: This is probably rare, but maybe you are trying to implement a method with high performance and using instance variables directly can save the cost of invoking a method.

If you want to know more, I recommend reading this iOS guide which describes in more detail the ideas I mention here.

Difference between self.variable name and classname.variable in python

If You want to count number of created Employee, You have to create method which will invoke to every objects at all (not individually).

To do that, create method and decorate her with @staticmethod. Notice that this method don't have self in parenthesies. Moreover create variable (here: count), which also invoke to every class object at all (without self. before).

Finally put our count variable inside __init__ method with += 1 equation (than every time when new Employee will be created __init__ will add +1 to our variable). But remember to add Employee. before count here, to count every single create Employee as a class population.

class Employee(object):
count = 0

@staticmethod
def status():
print(Employee.count)

def __init__(self, x):
self.x = x
Employee.count += 1
print("this method is executed")
print("Now, we have got", Employee.count, "Employees")


emp1 = Employee("John")

We can show up population number with :

print(emp1.count)
emp1.status()
print(Employee.count)


Related Topics



Leave a reply



Submit