Ruby self vs. Python self

Possible duplicate:
What is the difference between the versions of "self" Ruby and Python?

Ruby and Python are similar languages ​​that have the self keyword used in various situations. What does self mean in each language, and what are the differences?

+8
python ruby keyword self
source share
3 answers

As for Python, I can't tell you anything new. self usually passed as the first parameter to the method, as pst said. From Python Docs

Often the first argument to a method is called self. This is nothing more than a convention: the name "I" is completely irrelevant to Python. Please note, however, that by not complying with the convention, your code may be less readable by other Python programmers, and it is also possible that a class browser program may be written that relies on such convention.

CRUBY (or "MRI") has something similar that happens under the hood. Each C extension can define methods (module / class / singleton) in a Ruby class using

  • rb_define_method (instance)
  • rb_define_singleton_method (singleton class)
  • rb_define_module_function (class / module)

The actual implementation functions always take VALUE self as their first argument, similar to the Python idiom. self in these cases refers to the instance of the object to which this particular message is sent, i.e. if you have

  person = Person.new person.do_sth 

and do_sth will be implemented in C, then there will be a corresponding C function

 VALUE person_do_sth(VALUE self) { //do something return self; } 

Each such implementation should return a VALUE (C representation of the Ruby object), which refers to the fact that every method call or message sent (stick to the Smalltalk language) has a return value in Ruby. There is no void function in Ruby.

Although we need to pass self back and forth in low-level C code, you do not need to do this in Ruby code, Ruby will take care of this for you. The current value of self is stored internally in the current context of the thread that is running, so the existence of self provided, the message "self" will always evaluate some object.

Due to the dynamic nature of Ruby, the actual value of this object referenced by self changes with the current area of ​​code that is currently being interpreted. Run this to see for yourself:

 puts "#{self} - declared in global scope" # the 'top self' aka 'main' class << self puts "#{self} - 'main singleton class" # main singleton or 'eigenclass' end puts "Starting to interpret class A code" class A puts "#{self} - When do I get executed!?" # self is class A class << self puts "#{self} - And me!?" # now A singleton class def a # declaring method in class singleton class results in class method puts "#{self} - declared in singleton class" # it A end end def self.b puts "#{self} - declared in class method" # self is class A again -> class method class << self puts "#{self} - declared in Class A singleton class" # now it Class A singleton class end end def c puts "#{self} - declared in instance method" # self is instance of A class << self puts "#{self} - declared in instance singleton class" # now it the A instance singleton class end end end puts "All so far has happened simply by interpreting A code" a = A.new Aa Ab ac 

If you want to call the method / send the message from any context to self , you can do it explicitly (for example, self.method ) or omit self as the recipient - then, by convention, the implicit recipient of the message will be self .

An interesting note to this is the interpretation of Ruby's private methods, which differs, for example, from the concept of Java private . Ruby's private methods can only be called by sending a message using self as an implicit receiver, i.e.

 class A def a b end private def b puts "I'm private" end end a = A.new aa # => I'm private 

works, while replacing method a with

 def a self.b end 

will raise an exception. That means something very common in Java

 class A { private boolean compareUs(A a1, A a2) { ... } public boolean equals(A a1, A a2) { return (a1.compareUs() == a2.compareUs()); } } 

will not work in Ruby. A stupid example, but just to illustrate: in Java we can access the private methods of other instances of the same class, this is not possible in Ruby, because we can only access private methods of the current self .

Finally, to complicate things a bit, the instance_eval and class_eval functions will also change the value of self at runtime.

+8
source share

Ruby and Python are actually very different languages ​​(although they have a lot in common), even if Ruby has syntax that can be written as Python (with end keywords included); -)

Ruby is based on messages (it was heavily influenced by SmallTalk-80), and "messages" are sent to objects. Ruby supports an implicit receiver (explicitly known as self ) for this area. In Ruby, self not a variable, but rather an expression that evaluates in the context of the current object.

Python is property-based (due to the lack of a better term that I know) and is thus more like SELF and JavaScript, because functions are executed directly (instead of messages being transmitted). Python does not have the keyword self , and this is simply the convention that self used as the name of the first parameter of a method β€” how Python walks around the current context of an object.

Happy coding.

+14
source share

In Python, my_instance.a_method(an_argument) is just an abbreviation for MyClass.a_method(my_instance, an_argument) . Thus, the definition of MyClass.a_method must take two parameters:

 class MyClass(object): def a_method(self, an_argument): print self # self (the instance) is available in the method 

As pst said, using the variable name self is just a convention. You can also have

 class MyClass(object): def a_method(this_instance, an_argument): print this_instance 

and everything will work the same ... but don’t do it.

+9
source share

All Articles