En cuanto a Python no puedo decir nada nuevo. El self
se pasa convencionalmente como el primer parámetro de un método, como dijo pst. De Python docs
A menudo, el primer argumento de un método se llama self. Esto no es más que una convención: el nombre sí mismo no tiene ningún significado especial para Python. Sin embargo, tenga en cuenta que, al no seguir la convención, su código puede ser menos legible para otros programadores de Python, y también es concebible que se escriba un programa de navegador de clases que dependa de dicha convención.
CRuby (o 'MRI') tiene algo similar que sucede bajo el cofre.Cada extensión C puede definir (módulo/clase/singleton) métodos en una clase de Ruby utilizando
- rb_define_method (instancia)
- rb_define_singleton_method (clase singleton)
- rb_define_module_function (clase/módulo)
Las funciones de implementación reales siempre toman VALUE self
como su primer argumento, en analogía al modismo de Python. self
en estos casos se refiere a la instancia de objeto de este mensaje en particular se ha enviado a, es decir, si tiene
person = Person.new
person.do_sth
y do_sth pasaría a ser implementado en C, entonces no habría una función de C correspondiente
VALUE
person_do_sth(VALUE self) {
//do something
return self;
}
cada dicha aplicación tiene para devolver una (la representación C de un objeto de Rubí) VALUE
, que se refiere al hecho de que cada llamada de método o mensaje enviado (a pegarse a Smalltalk jerga) tiene un valor de retorno en Ruby. No existe la función void
en Ruby.
Aunque necesitamos pasar self
hacia adelante y hacia atrás en el código C de bajo nivel, no necesita hacerlo en el código Ruby, Ruby se encarga de esto por usted. El valor actual de uno mismo se almacena internamente en el contexto de subproceso actual que se ejecuta, por lo que se concede la existencia de self
, el mensaje "self" siempre evaluará a algún objeto.
Debido a la naturaleza dinámica de Ruby, el valor real de este objeto al que se hace referencia en self
cambia con el alcance actual del código que se interpreta actualmente. Ejecutar este a ver por sí mismo:
puts "#{self} - declared in global scope" # the 'top self' aka 'main'
class << self
puts "#{self} - 'main's singleton class" # main's 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's singleton class
def a # declaring method in class's singleton class results in class method
puts "#{self} - declared in singleton class" # it's 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's singleton class" # now it's Class A's singleton class
end
end
def c
puts "#{self} - declared in instance method" # self is instance of A
class << self
puts "#{self} - declared in instance's singleton class" # now it's the A instance's singleton class
end
end
end
puts "All so far has happened simply by interpreting A's code"
a = A.new
A.a
A.b
a.c
Si desea llamar a un método/enviar un mensaje desde cualquier contexto a self
, usted puede hacer esto de manera explícita (por ejemplo self.method
) o se omite self
como el receptor - a continuación, Por convención, el receptor implícito del mensaje será self
.
Una nota interesante al respecto es la interpretación de Ruby de los métodos private
, que difiere, p. de la noción de Java de private
. métodos privados de Ruby sólo son exigibles mediante el envío de un mensaje usando self
como un receptor implícito, es decir
class A
def a
b
end
private
def b
puts "I'm private"
end
end
a = A.new
a.a # => I'm private
obras, mientras que la sustitución de un método por
def a
self.b
end
elevaría una excepción. Esto implica que algo muy común en Java
class A {
private boolean compareUs(A a1, A a2) { ... }
public boolean equals(A a1, A a2) {
return (a1.compareUs() == a2.compareUs());
}
}
no funcionará en Ruby. Ejemplo tonto, pero solo para ilustrar el punto: en Java podemos acceder a métodos privados de otras instancias de la misma clase, esto no sería posible en Ruby porque solo podemos acceder a métodos privados del actual self
.
Finalmente, para complicar las cosas un poco más, las funciones instance_eval
y class_eval
también alterarán el valor de self
durante la ejecución.
Python no tiene la palabra clave 'self'. Solo es usado por convención. –