Nested methods

Ciao,
sono nuovo nel linguaggio ruby e sto cercando delucidazioni relative
alla definizione dei “nested methods”. Il seguente codice:

class Myclass
def m1
def m2
puts “m2”
end
puts “m1”
end
end

a = Myclass.new
a.m1
a.m2

b = Myclass.new
b.m2

fornisce come output:

m1
m2
m2

Per quale motivo il metodo m2 diventa un metodo di istanza della classe
Myclass allo stesso modo di m1 ?

Se poteste consigliarmi una risorsa chiara ve ne sarei molto grato,
barancolo nel buio…

Pietro

— Pietro M. [email protected] wrote:

Ciao,
sono nuovo nel linguaggio ruby e sto cercando
delucidazioni relative
alla definizione dei “nested methods”.

in breve: non esistono.
Se vieni da un background pythonesco forse stai
pensando alle nested function, ma in ruby non si
possono fare (ok, escludendo l’uso di Proc).

Quando definisci un metodo, lo fai sempre rispetto a
un oggetto/modulo/clase corrente, quindi:

end

a = Myclass.new
a.m1

a questo punto esegui il metodo m1.
Il corpo del metodo è “definisci un metodo m2 in
questa classe/oggetto/modulo”, e quindi fa esattamente
quello.

a.m2

e ovviamente qua te lo richiama

b = Myclass.new
b.m2

il metodo è appunto stato definito come se fosse nella
classe, per cui ora fa parte di qualsiasi istanza.

Per quale motivo il metodo m2 diventa un metodo di
istanza della classe
Myclass allo stesso modo di m1 ?

Se poteste consigliarmi una risorsa chiara ve ne
sarei molto grato,
barancolo nel buio…

spero di averti chiarito un po’ i dubbi… ad ogni
modo, per quale motivo volevi definire dei metodi
annidati?

  ___________________________________________________________

Want ideas for reducing your carbon footprint? Visit Yahoo! For Good
http://uk.promotions.yahoo.com/forgood/environment.html

Ciao Gabriele,
ti ringrazio molto per la tua risposta, soprattutto la parte
<<“definisci un metodo m2 in questa classe/oggetto/modulo”, e quindi fa
esattamente
quello.>> che direi mi è molto utile. Sono un programmatore java e sto
imparando ruby in questi giorni leggendo un libro (la seconda edizione
di “Pragmatic ecc…”). L’esempio che ho riportatto sul forum si ispira
ad un esempio riportato sul medesimo libro, che però non forniva una
risposta troppo soddisfacente, per me almeno. Mi sembra comunque che
questi nested method non siano molto usati, o forse mi sbaglio ?

Pietro

gabriele renzi wrote:

— Pietro M. [email protected] wrote:

Ciao,
sono nuovo nel linguaggio ruby e sto cercando
delucidazioni relative
alla definizione dei “nested methods”.

in breve: non esistono.
Se vieni da un background pythonesco forse stai
pensando alle nested function, ma in ruby non si
possono fare (ok, escludendo l’uso di Proc).

Quando definisci un metodo, lo fai sempre rispetto a
un oggetto/modulo/clase corrente, quindi:

end

a = Myclass.new
a.m1

a questo punto esegui il metodo m1.
Il corpo del metodo � “definisci un metodo m2 in
questa classe/oggetto/modulo”, e quindi fa esattamente
quello.

a.m2

e ovviamente qua te lo richiama

b = Myclass.new
b.m2

il metodo � appunto stato definito come se fosse nella
classe, per cui ora fa parte di qualsiasi istanza.

Per quale motivo il metodo m2 diventa un metodo di
istanza della classe
Myclass allo stesso modo di m1 ?

Se poteste consigliarmi una risorsa chiara ve ne
sarei molto grato,
barancolo nel buio…

spero di averti chiarito un po’ i dubbi… ad ogni
modo, per quale motivo volevi definire dei metodi
annidati?

  ___________________________________________________________

Want ideas for reducing your carbon footprint? Visit Yahoo! For Good
http://uk.promotions.yahoo.com/forgood/environment.html

Quello che deduco dalla risposta di Gabriele è che esisterebbe il
concetto di “contesto”: m2 viene definito come metodo di istanza in
quanto m1 è definito come tale nel contesto di Myclass; analogamente il
seguente codice:

def metodo1
def metodo2
puts “metodo2”
end
end
metodo1
metodo2

definisce “metodo2” come metodo di classe di Object perchè questo è il
contesto.
Mi pare che questo concetto (ammesso che non sia solo una mia invenzione
:slight_smile: non sia molto chiaro. E’ il mio modo di pensare che è errato o un
concetto di contesto esiste veramente ? in tal caso esiste una risorsa
in cui sia spiegato (o è tutto contenuto nella frase della risposta di
Gabriele che ho sottolineato nel mio post precedente) ?

Pietro

Pietro M. wrote:

Ciao Gabriele,
ti ringrazio molto per la tua risposta, soprattutto la parte
<<“definisci un metodo m2 in questa classe/oggetto/modulo”, e quindi fa
esattamente
quello.>> che direi mi è molto utile. Sono un programmatore java e sto
imparando ruby in questi giorni leggendo un libro (la seconda edizione
di “Pragmatic ecc…”). L’esempio che ho riportatto sul forum si ispira
ad un esempio riportato sul medesimo libro, che però non forniva una
risposta troppo soddisfacente, per me almeno. Mi sembra comunque che
questi nested method non siano molto usati, o forse mi sbaglio ?

Pietro

gabriele renzi wrote:

— Pietro M. [email protected] wrote:

Ciao,
sono nuovo nel linguaggio ruby e sto cercando
delucidazioni relative
alla definizione dei “nested methods”.

in breve: non esistono.
Se vieni da un background pythonesco forse stai
pensando alle nested function, ma in ruby non si
possono fare (ok, escludendo l’uso di Proc).

Quando definisci un metodo, lo fai sempre rispetto a
un oggetto/modulo/clase corrente, quindi:

end

a = Myclass.new
a.m1

a questo punto esegui il metodo m1.
Il corpo del metodo � “definisci un metodo m2 in
questa classe/oggetto/modulo”, e quindi fa esattamente
quello.

a.m2

e ovviamente qua te lo richiama

b = Myclass.new
b.m2

il metodo � appunto stato definito come se fosse nella
classe, per cui ora fa parte di qualsiasi istanza.

Per quale motivo il metodo m2 diventa un metodo di
istanza della classe
Myclass allo stesso modo di m1 ?

Se poteste consigliarmi una risorsa chiara ve ne
sarei molto grato,
barancolo nel buio…

spero di averti chiarito un po’ i dubbi… ad ogni
modo, per quale motivo volevi definire dei metodi
annidati?

  ___________________________________________________________

Want ideas for reducing your carbon footprint? Visit Yahoo! For Good
http://uk.promotions.yahoo.com/forgood/environment.html

— Pietro M. [email protected] wrote:

Quello che deduco dalla risposta di Gabriele è che
esisterebbe il
concetto di “contesto”: m2 viene definito come
metodo di istanza in
quanto m1 è definito come tale nel contesto di
Myclass;

il contesto è la classe/modulo corrente. Classi e
moduli sono sostanzialmente la stessa cosa, ricorda :wink:

L’unico dettaglio, credo, è che se usi def…end la
classe è determinata lessicalmente, nel senso che il
parser sa che stai lavorando dentro la classe C, e
quindi il metodo verrà definito in C.

Diversamente, se usi self.m2:

class C1
def m1
def self.m2() “m2” end
end
end
=> nil
c1=C1.new
=> #C1:0xb7aebbb0
c1.m1
=> nil
c1.m2
=> “m2”
c2=C1.new
=> #C1:0xb7ae2934
c2.m2
NoMethodError: undefined method `m2’ for
#C1:0xb7ae2934
from (irb):32
from :0

In questo caso la classe che contiene il metodo è la
singleton class dell’istanza c1, e quindi non c’è
inquinamento del namespace della classe C1.

definisce “metodo2” come metodo di classe di Object
perchè questo è il
contesto.

I metodi che definisci fuori da una classe sono
trattati in modo speciale, per evitare la fatica di
dover scrivere ogni volta class Object… end

Essi vengono definiti come metodi privati del modulo
Kernel, che è incluso in Object, e quindi di
conseguenza li trovi ovunque (anche in Kernel, perché
Kernel.is_a?Object :slight_smile:

def m
end
=> nil
Kernel.methods.grep(/m$/)
=> [“m”, “system”, “require_gem”, “gem”]
Object.is_a?Kernel
=> true
Object.new.is_a?Kernel
=> true
Kernel.is_a?Object
=> true

Mi pare che questo concetto (ammesso che non sia
solo una mia invenzione
:slight_smile: non sia molto chiaro.

in generale è meglio se non te ne preoccupi :wink:
La regola è: se stai dentro una classe/modulo/oggetto,
i metodi rimangono lì.
Se stai nel modulo “main”, ovvero fuori da ogni
definizione, i metodi vanno a finire dentro Object,
come metodi privati.

E’ il mio modo di pensare
che è errato o un
concetto di contesto esiste veramente ? in tal caso
esiste una risorsa
in cui sia spiegato (o è tutto contenuto nella
frase della risposta di
Gabriele che ho sottolineato nel mio post
precedente) ?

credo che sia tutto quel che c’è da dire… l’unica
cosa omessa, credo, è “quale è la classe o modulo
quando definsco metodi singleton?”

ovvero:

a= Object.new
=> #Object:0xb7c983dc
def a.m() “singleton” end
=> nil
a.m
=> “singleton”

In questo caso esiste sempre quello che tu chiami
contesto, ed è la singleton class, che altro non è che
una classe invisibile messa tra l’oggetto e la sua
classe originale.
Ma in generale sono dettagli di cui non vale la pena
interessarsi (io incolpo rails per aver diffuso
l’abuso delle singleton class, che secondo matz erano
un dettaglio implementativo :wink:

Comunque i metodi annidati non sono molto usati. No,
meglio, non li ho mai visti usare. O ancora, non li ho
mai visti usare se non per errore :slight_smile:

  ___________________________________________________________

Yahoo! Answers - Got a question? Someone out there knows the answer. Try
it
now.

— Antonio Di fluri [email protected] wrote:

ciao volevo far notare un comportamento riguardo i
metodi innestati:

commenti a riguardo?

conferma quello che dicevamo, no?

  ___________________________________________________________

Yahoo! Answers - Got a question? Someone out there knows the answer. Try
it
now.

direi di si, anche se non posso provare il codice fino a stasera :wink:

ciao volevo far notare un comportamento riguardo i metodi innestati:

def my_methods_only(myClass)
superClass=myClass.class.superclass
return myClass.methods - superClass.methods
end

class Myclass
def m1
def m2
puts “m2”
end
puts “m1”
end
end

a = Myclass.new

p 'prima di chiamare a.m1 ’
p my_methods_only(a)

puts ‘chiamo:’
a.m1
puts ‘fine chiamata’

p 'dopo aver chiamato a.m1 ’
p my_methods_only(a)

commenti a riguardo?

ciao a tutti da un nuovo iscritto al forum

Caratteristica di ruby mi pare infatti che TUTTO sia runtime, a
differenza di java dove una classe una volta definita è fissa e
immutabile (affermazione che in realtà non è esatta, dato che con le
reflection è possibile modificare le caratteristiche di una classe
runtime…)

In altri termini: il momento in cui l’interprete ruby esegue “def…”
viene cambiata la struttura dati “interna” che rappresenta la
classe/modulo/singleton class.

Antonio Di Fluri wrote:

l’output del codice e’ il seguente:

—inizio output—
"prima di chiamare a.m1 "
[“m1”]
chiamo:
m1
fine chiamata
"dopo aver chiamato a.m1 "
[“m1”, “m2”]

Program exited with code 0
—fine output—

mio commento:
la cosa interessante e’ che il metodo m2 innestato in m1 non e’
riconosciuto come metodo dell’istanza se non e’ chiamato almeno una
volta il metodo m1 (dinamicita’ linguaggi interpretati?)
NOTA: nell’output

Ancora non mi raccapezzo con i termini reflection, duck typing etc etc,
ma il fatto che tu mi dici che anche java permette di cambiare una
classe a runtime mi rende inquieto in quanto potrei ritornare dinuovo a
programmare in java e trascurare ruby (sono un newbie in ruby)

l’output del codice e’ il seguente:

—inizio output—
"prima di chiamare a.m1 "
[“m1”]
chiamo:
m1
fine chiamata
"dopo aver chiamato a.m1 "
[“m1”, “m2”]

Program exited with code 0
—fine output—

mio commento:
la cosa interessante e’ che il metodo m2 innestato in m1 non e’
riconosciuto come metodo dell’istanza se non e’ chiamato almeno una
volta il metodo m1 (dinamicita’ linguaggi interpretati?)
NOTA: nell’output

bhe, ti assicuro che per cambiare una classe in java ci vogliono molte
righe di codice, mentre in ruby puoi scrivere cose del tipo:

class Myclass
if some_variable == 1
def

end
else
def

end
end

il che è molto più leggibile e facile che in java. Inoltre molti
framework java (Hibernate, Spring) fanno uso pesante delle reflection
per modificare classi runtime, di gatto usando java come un linguaggio
dinamico.

Di certo ruby contiene concetti differenti da java, non bisogna pensare
che siano cose uguali espresse con una sintassi diversa.
Personalmente credo valga la pena appassionarsi a ruby, tenendo ben
presente che è DIVERSO da java. Il libro “Pragmatic Bookshelf -
programming ruby -2nd edition” che sto leggendo mi pare una ottima
fonte.

Antonio Di Fluri wrote:

Ancora non mi raccapezzo con i termini reflection, duck typing etc etc,
ma il fatto che tu mi dici che anche java permette di cambiare una
classe a runtime mi rende inquieto in quanto potrei ritornare dinuovo a
programmare in java e trascurare ruby (sono un newbie in ruby)