Il giorno lun, 04/06/2007 alle 22.58 +0200, [L]ash ha scritto:
ho aggiunto la direttiva private
mi scuso se la domanda è banale o mal posta ma è da poco che mi sono
avvicinato a ruby
Non ho neanche idea se si possa rendere una classe privata; non mi è mai
capitata la necessità di farlo. Sei sicuro che rendere la classe privata
sia la soluzione migliore al problema che vuoi risolvere? Cosa vuoi
ottenere rendendola privata?
Non ne ho mai avuto bisogno, ma potresti forse provare a fare:
class A
class B
private
def initialize
end
def metodo1
end
def metodo2
end
end
end
Così avresti tutti i metodi di B privati, e anche se B stessa non è
privata il risultato pratico è uguale (o quanto meno molto simile).
Sinceramente non so cosa succede se hai ‘initialize’ come private e
cerchi di creare un’istanza di B…
Il giorno Tue, 05 Jun 2007 08:52:14 +0200
Giovanni C. [email protected] ha scritto:
Cosa vuoi ottenere rendendola privata?
semplice incapsulazione.
mi chiedo… in un linguaggio così basato sulle convenzioni come ruby,
possiamo ancora pensare all’encapsulation alla vecchia maniera? vi siete
mai
ritrovati a chiedervelo?
Il giorno Tue, 5 Jun 2007 13:20:37 +0200
“chiaro scuro” [email protected] ha scritto:
mi chiedo… in un linguaggio così basato sulle convenzioni come ruby,
possiamo ancora pensare all’encapsulation alla vecchia maniera? vi
siete mai ritrovati a chiedervelo?
non vedo come possano centrare le convenzioni con l’incapsulamento,
sarà che sono nuovo al ruby e mi sfugge qualcosa
non mi sono spiegato bene. volevo dire… con Ruby sei così libero che ogni
encapsulation è in realtà farlocca, quindi anche un private diventa più
un
suggerimento al programmatore dell’intento del coder originario che
qualcosa
che viene forzato.
Il giorno mar, 05/06/2007 alle 13.20 +0200, chiaro scuro ha scritto:
mi chiedo… in un linguaggio così basato sulle convenzioni come ruby,
possiamo ancora pensare all’encapsulation alla vecchia maniera? vi siete mai
ritrovati a chiedervelo?
Scusa, quale sarebbe l’incapsulamento alla vecchia maniera?
Il giorno Tue, 5 Jun 2007 15:32:28 +0200
“chiaro scuro” [email protected] ha scritto:
non mi sono spiegato bene. volevo dire… con Ruby sei così libero che
ogni encapsulation è in realtà farlocca, quindi anche un private
diventa più un suggerimento al programmatore dell’intento del coder
originario che qualcosa che viene forzato.
credo che una buona incapsulazione deve essere fatta a priscindere dal
linguaggio e se questa possa essere mantenuta tale o se il clinet
puo accedervi. L’incapsulazione permette di “nascondere” al client
aspetti che non gli devono interessare e che a cui possibilmente non
deve neanche accedere in quanto dettagli implementativi
dell’interfaccia che sta usando. Se un programmatore usa delle funzioni
marcate come private sicuramente non sta facendo un buon lavoro in
quanto quel codice può essere sottoposto a modifiche senza che gli sia
detto rendendo il suo codice del tutto inutilizzabile (queste
funzioni fanno parte dei dettagli implementativi che non gli devono
interessare); mentre invece l’interfaccia (parte public) viene mantenuta
il più possibile inalterata o cmq viene specificato ad ogni rilascio
quali modifiche sono state apportate alle interfacce pubbliche
linguaggio e se questa possa essere mantenuta tale o se il clinet
puo accedervi. L’incapsulazione permette di “nascondere” al client
aspetti che non gli devono interessare e che a cui possibilmente non
certo, concordo con te. sottolineavo solo che in ruby l’encapsulation
è più
un accordo amichevole che una regola che viene forzata.
per dirla tutta, se dovessi scrivere #private come commento invece di
private come istruzione mi andrebbe quasi bene uguale.
Il giorno mar, 05/06/2007 alle 15.32 +0200, chiaro scuro ha scritto:
semplice incapsulazione.
non mi sono spiegato bene. volevo dire… con Ruby sei così libero che ogni
encapsulation è in realtà farlocca, quindi anche un private diventa più un
suggerimento al programmatore dell’intento del coder originario che qualcosa
che viene forzato.
Un attimo: “incapsulamento” è il fatto che lo stato dell’oggetto e la
sua organizzazione interna siano locali e privati dell’oggetto stesso, e
che solo esso possa modificarli. Per ottenere una modifica dello stato
dell’oggetto occorre mandargli dei messaggi che rispettino il protocollo
dell’oggetto stesso.
Da questo punto di vista, l’incapsulamento offerto di default da Ruby
(ovvero che le variabili di istanza non possano che essere private) sta
un gradino sopra rispetto a quello offerto da Java o anche da Python.
Per questo la richiesta di [L]ash di creare una classe privata ad
un’altra classe mi sembra strana: se lo stato dell’oggetto è giÃ
privato, racchiuderlo in un’altra struttura che dovrebbe essere comunque
proprietà privata dell’oggetto stesso mi sembra quantomeno inutile.
Quello di cui parli tu è una cosa diversa, ovvero il controllo di
accesso dei metodi.
perchè, nel mio caso, B è una classe ausiliaria di A che serve solo e
soltanto nei dettagli implementativi di A e non viene passata all
esterno di essa; quindi mi viene naturale porla all interno di A.
Il fatto che si possa istanziare una variabile di quella classe non crea
particolari problemi in se (potrebbe farlo se fosse una classe
singleton) ma mi da fastidio che sia possibile accedere ai dettagli.
Ok, abbiamo capito - direi - tutti il concetto e l’utilitÃ
dell’encapsulation, ma mi sfugge un attimo il tuo punto (e sono davvero
interessato a capirne di più! non sto facendo retorica!). Non so se si
possa rendere una classe private in Ruby, ma direi di no. Ok. Ma se
fosse possibile, cosa guadagneresti in termini pratici, nel tuo caso
specifico? Mi puoi aiutare a capire meglio dove sta il rischio che uno
corre scrivendo codice con i soli meccanismi di encapsulation di Ruby?
Il fatto che si possa istanziare una variabile di
quella classe non crea
particolari problemi in se (potrebbe farlo se fosse
una classe
singleton) ma mi da fastidio che sia possibile
accedere ai dettagli.
e’ una cosa abbastanza comune per chi passa a
ruby/python da java/c++ in genere, preoccuparsi della
visibilità.
In generale in ruby è possibile accedere a tutto
tramite reflection, quindi pui solo rendere la cosa
meno ovvia.
Nel tuo caso il trucco c’è: usa una variabile invece
di una costante:
@@Klasse = Class.new(SuperClasse) do
def metodo… end
end
ma anche questo può essere scavalcato grazie alla
reflection.
In generale la soluzione migliore è semplicemente di
mettere un commento :nodoc: in modo da non documentare
l’esistenza della tua classe, e far capire a chi
guarda i sorgenti che quella classe è solo per uso interno.
Ok, allora la prima cosa da fare per imparare Ruby è dimenticare tutto
quello che C++ ti ha insegnato nel campo della OOP.
esagerato
“I invented the term ‘Object-Oriented’, and I can tell you I did not
have C++ in mind.” --AlanKay
;-PPPP
in generale direi che l’atteggiamento ruby verso l’OOP
rispetto a C++ è:
tutto è un oggetto
e soprattutto gli oggetti interagiscono tramite messaggi . Se c’è una
cosa da portare a casa dopo aver incontrato Ruby o Smalltalk, è
l’interazione tramite messaggi.