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?
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 ?
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?
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
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 ?
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?
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
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
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
non sia molto chiaro.
in generale è meglio se non te ne preoccupi
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?”
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
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
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)
—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)
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.