PDA

View Full Version : Il vostro linguaggio di programmazione fa schifo, qualunque esso sia


Pagine : [1] 2

71104
07-08-2008, 12:17
Thread ufficiale del comitato di manutenzione della pagina YourLanguageSucks (http://wiki.theory.org/YourLanguageSucks) :asd:

poiché in questo forum abbastanza spesso si leggono critiche assolutamente sensate ai maggiori linguaggi di programmazione (non dimenticherò mai quanto fa cagare PHP :asd: grazie cdimauro :D) allora ho aperto questo thread dove potete sia proporre nuove critiche da muovere nella suddetta pagina, sia discutere critiche attualmente presenti ma opinabili, eventualmente da rimuovere.

inoltre in certi casi le critiche presenti nella pagina hanno senso, ma sono troppo generiche e quindi contestabili; necessiterebbero di esempi più specifici e a prova di critica. vedere ad esempio il quinto punto nel paragrafo sul C++:
"The nature of C++ has led developers to write compiler dependent code, creating incompatiblity between different compilers and even different versions of the same compiler."

è possibile iscriversi gratuitamente al sito, quindi tutti quanti potete editare la pagina; non vandalizzatela e non scrivete cavolate, ci tengo a questa perla di internet :D

PS: special thanks to DanieleC88 :D

cdimauro
07-08-2008, 13:51
Di niente, per me era un dovere. :D

P.S. E non hai visto Perl! :asd:

Antares88
07-08-2008, 19:22
lol ma che cos'è questa pagina tanto lollosa quanto vera ?

ndakota
07-08-2008, 19:52
non è vero, il malbolge non fa schifo :p

cdimauro
07-08-2008, 21:35
Evviva! Sono riuscito a recuperare un po' di post in cui spiegavo perché PHP è una merda di linguaggio! :p

Ecco qui:

http://www.hwupgrade.it/forum/showpost.php?p=9275523
http://www.hwupgrade.it/forum/showpost.php?p=12379222
http://www.hwupgrade.it/forum/showpost.php?p=17441292
http://www.hwupgrade.it/forum/showpost.php?p=17570935
http://www.hwupgrade.it/forum/showpost.php?p=17576227

Divertitevi. :asd:

71104
07-08-2008, 21:58
quando hai un po' di tempo potresti scrivere qualcosa su YourLanguageSucks? :D

cdimauro
07-08-2008, 22:58
Per queste cose il tempo lo si DEVE trovare. :asd:

DanieleC88
08-08-2008, 00:49
PS: special thanks to DanieleC88 :D
Addirittura! :eek: Ma grazie! :cool:
Comunque ormai è ufficiale: la mia IronMemory ormai è andata del tutto, ricordo più o meno che quella pagina l'avevo trovata io, ma non ricordo più né come né perché... :stordita:

Non posso non iscrivermi a questo thread, sento che ne vedremo delle belle... e in effetti già i post di cdimauro su PHP sono favolosi. :asd:

Infrid
09-08-2008, 09:57
Evviva! Sono riuscito a recuperare un po' di post in cui spiegavo perché PHP è una merda di linguaggio! :p

Ecco qui:

http://www.hwupgrade.it/forum/showpost.php?p=9275523
http://www.hwupgrade.it/forum/showpost.php?p=12379222
http://www.hwupgrade.it/forum/showpost.php?p=17441292
http://www.hwupgrade.it/forum/showpost.php?p=17570935
http://www.hwupgrade.it/forum/showpost.php?p=17576227

Divertitevi. :asd:

come programmatore in php da anni...QUOTO

andbin
09-08-2008, 11:31
Mi permetto di segnalare alcune cose che ho letto in quella pagina riguardo a Java che reputo non corrette o comunque dubbie.

* Everything is in objects and must be buffered, even those things that don't really need to be buffered or in objects.

Stando alle mie conoscenze di inglese, lo tradurrei così: "Tutto è un oggetto e deve essere bufferizzato, anche quelle cose che non hanno veramente bisogno di essere bufferizzate o in oggetti."

Ora .. le mie conoscenze di inglese sono certamente limitate .... ma ho sbagliato a tradurre io??? Perché altrimenti non trovo un gran senso in questa frase ...


* Supports goto

No, Java non ha un costrutto goto!! goto come anche const sono parole chiave riservate del linguaggio, per motivi più che altro "storici". Ma non sono usate.


Anche il primo punto:
* Exceptions as part of the type system means you have to catch every imaginable exception that might be thrown. This makes it hard to rapidly prototype or quickly test out several methods of solving a problem.

è discutibile. In Java esiste una netta e chiara distinzione tra eccezioni "checked" e "unchecked". Una eccezione come FileNotFoundException è checked perché il fatto che un file non esiste è una situazione che può accadere in un mondo "reale", es. un utente ha indicato un nome di file non presente. Quindi il non aver trovato un file non denota un "baco" del programma e pertanto tale situazione deve essere presa in considerazione.

Se invece salta fuori un ArrayIndexOutOfBoundsException o un NullPointerException o un ClassCastException (tutte "unchecked"), quasi certamente è dovuto ad un "baco" del programma. Cioè è il programmatore che ha sbagliato ad usare metodi, variabili, costrutti o altro (magari anche solo perché non ha letto bene la documentazione di un metodo).
Essendo unchecked non si è costretti a prendere in considerazione queste eccezioni e infatti generalmente non le si cattura/gestisce.
Piuttosto che gestire queste eccezioni bisognerebbe "gestire" il programmatore, ovvero ricoprirlo di catrame e rotolarlo nelle piume .... :D

71104
09-08-2008, 11:34
cdimauro, anzitutto grazie per aver aggiunto quella miriade di note di demerito per PHP :D

però ci sono un paio di punti per i quali non è chiaro quale sia l'aspetto negativo:

there are two ways for end-of-line comments: // and #
code must be inserted between <?php and ?> tags
embè? qual è il problema?

poi c'è un punto sul quale sarebbe meglio fare un esempio di codice per vedere quali effetti nefasti potrebbero esserci all'atto pratico:
an integer operation overflow automatically converts the type to float


per il resto, ogni volta PHP non fa che stupirmi :asd: :asd: :asd:

71104
09-08-2008, 11:42
Mi permetto di segnalare alcune cose che ho letto in quella pagina riguardo a Java che reputo non corrette o comunque dubbie. la pagina puoi editarla anche tu! :)
se però non sei strasicuro di una cosa prima è meglio che ti limiti a segnalarla nella pagina di discussione.


* Everything is in objects and must be buffered, even those things that don't really need to be buffered or in objects.

Stando alle mie conoscenze di inglese, lo tradurrei così: "Tutto è un oggetto e deve essere bufferizzato, anche quelle cose che non hanno veramente bisogno di essere bufferizzate o in oggetti."

Ora .. le mie conoscenze di inglese sono certamente limitate .... ma ho sbagliato a tradurre io??? Perché altrimenti non trovo un gran senso in questa frase ... si infatti ti do ragione, quella frase non l'ho mai capita manco io... forse si riferiva ad una sua immaginaria politica di programmazione che vige tra i programmatori Java (quella di bufferizzare ogni singola cosa?), ma mi sembra un'affermazione piuttosto idiota. mi sa che la tolgo.


* Supports goto

No, Java non ha un costrutto goto!! goto come anche const sono parole chiave riservate del linguaggio, per motivi più che altro "storici". Ma non sono usate. grazie per la segnalazione. quel punto si trasforma dritto dritto in "Java has unused keywords, such as goto and const." :D


Anche il primo punto:
* Exceptions as part of the type system means you have to catch every imaginable exception that might be thrown. This makes it hard to rapidly prototype or quickly test out several methods of solving a problem.

è discutibile. [...] non me la sento di rimuovere quel punto. piuttosto preciserei sulle eccezioni checked e ci metterei un link esterno a questa pagina: http://www.artima.com/intv/handcuffs.html

cdimauro
09-08-2008, 21:49
come programmatore in php da anni...QUOTO
C'è ancora molto da dire. Ogni tanto segui il wiki a cui è dedicato questo thread. :D
cdimauro, anzitutto grazie per aver aggiunto quella miriade di note di demerito per PHP :D
Ho appena cominciato, dai. :p

E quando avrò finito voglio vedere chi avrà ancora voglia di lavorarci... :asd:
però ci sono un paio di punti per i quali non è chiaro quale sia l'aspetto negativo:
embè? qual è il problema?
Nel primo caso il problema è che per la STESSA IDENTICA operazione sono presenti due sintassi diverse: che motivo c'è?

Hanno voluto utilizzare il # per far contenti i programmatori Unix e // per quelli C++. :stordita:

Quanto al secondo punto, ti pare normale che un qualunque programma debba iniziare con quei due astrusi tag? :stordita:
poi c'è un punto sul quale sarebbe meglio fare un esempio di codice per vedere quali effetti nefasti potrebbero esserci all'atto pratico:
Al momento mi viene in mente la memorizzazione del dato calcolato in un campo di un db che è di tipo intero: a seconda dell'engine potrebbero esserci delle sorprese, tipo che viene memorizzato il massimo valore rappresentabile per quel campo (strada seguita da MySQL, se non erro) oppure il sollevamento di un'eccezione di arithmetic overflow.
per il resto, ogni volta PHP non fa che stupirmi :asd: :asd: :asd:
E continuerà ancora a farlo per un po'... :D

astorcas
10-08-2008, 15:32
mi iscrivo! Sul PHP si potrebbe scrivere una PHP Suckspedia, la pagina sembra già a buon punto!
Sul C# niente da obiettare?

71104
10-08-2008, 16:36
mi iscrivo! Sul PHP si potrebbe scrivere una PHP Suckspedia, la pagina sembra già a buon punto!
Sul C# niente da obiettare?
aveva scritto gugoXX un po' di roba in un altro topic, gli avevo chiesto di metterlo anche su YourLanguageSucks, ma niente. comunque non t'aspettare chissacché eh, saranno più o meno lo stesso numero di punti che puoi trovare nel paragrafo su Java; ai livelli di PHP non c'arriva nessuno :asd:

cdimauro
10-08-2008, 16:36
In effetti di materiale su PHP ce n'è a josa. :asd:

Comunque, sì, sono a buon punto: mi manca di finire con le classi e le eccezioni, e dovrebbe essere completa (poi se vi vengono in mente altre cose, aggiungete pure, eh! :D). :cool:

71104
10-08-2008, 16:40
Nel primo caso il problema è che per la STESSA IDENTICA operazione sono presenti due sintassi diverse: che motivo c'è? non c'è motivo ma mi pare che non ci sia neanche problema; anzi, (leggi sotto)

Hanno voluto utilizzare il # per far contenti i programmatori Unix e // per quelli C++. :stordita: appunto, quindi hanno fatto contenti tutti; che problema c'è? :D


Quanto al secondo punto, ti pare normale che un qualunque programma debba iniziare con quei due astrusi tag? :stordita: e sennò come lo inserisci il codice in mezzo all'HTML? oppure intendi che devono cominciare con quel tag anche i programmi standalone, non mischiati all'HTML? :D
in questo secondo caso è pazzesco :asd:

astorcas
10-08-2008, 16:58
aveva scritto gugoXX un po' di roba in un altro topic, gli avevo chiesto di metterlo anche su YourLanguageSucks, ma niente. comunque non t'aspettare chissacché eh, saranno più o meno lo stesso numero di punti che puoi trovare nel paragrafo su Java; ai livelli di PHP non c'arriva nessuno :asd:

Non ne dubito... :asd: io cmq qualcosa che non digerisco tanto bene del c# ce l'ho, casomai trovando il tempo se ne discute un po' :fagiano:

Metto le mani avanti dicendo che a prescindere da questo mi sta facilitando parecchio la vita (insieme col Python, per la gioia di cdimauro ;) )

FagioloOne
10-08-2008, 17:00
Sto lavorando per creare un video game ed effettivamente java preferisce lavorare usando un uso smodato di Buffer anche dove tu ti chiedi il perche'.


Per le eccezioni su java acchiapparle tutte e' veramente uno strazio e' brutto non gestire anche quelle non obligatorie. (Mio personale modo di programmare)

Sarebbe interessante vedere anche quante critiche si possono fare al linguaggio di scrit bash, la veramente certe cose sono assurde.

marko.fatto
10-08-2008, 17:01
era un po' che non leggevo...
cavolo quanto si è allungato php :asd:

71104
10-08-2008, 18:10
Sto lavorando per creare un video game ed effettivamente java preferisce lavorare usando un uso smodato di Buffer anche dove tu ti chiedi il perche'. io non è che sono il primo venuto per quanto riguarda Java: in Java ci sto programmando anche io in questo periodo per la tesi e comunque ci programmo da anni; ma tutta questa inutile bufferizzazione non credo d'averla mai vista.


Per le eccezioni su java acchiapparle tutte e' veramente uno strazio e' brutto non gestire anche quelle non obligatorie. (Mio personale modo di programmare) devi acchiapparle tutte. la situazione sulle eccezioni in realtà è parecchio complessa: andbin ha spiegato molto eloquentemente la differenza tra quelle checked e quelle unchecked e i loro rispettivi significati, quindi se tu ipoteticamente non catturassi delle eccezioni checked il tuo programma sarebbe semplicemente buggato, perché non gestirebbe determinati casi d'errore che non dipendono da te, ma che si possono benissimo verificare anche se il tuo programma è perfetto (esempio: mia sorella inciampa in un cavo ethernet :D). in altre parole Java ti obbliga ad eliminare alcuni tipi di bug. tuttavia è anche vero quello che il team di C# ha risposto a Bruce Eckel nell'intervista (vedi qua: http://www.artima.com/intv/handcuffs.html), ovvero che certe volte il numero di possibile eccezioni (checked, aggiungo io) che un pezzo di codice potrebbe lanciare è spropositato, e chi usa quel pezzo di codice fa un banale "catch (Exception e)" e le gestisce tutte allo stesso modo; un difetto di Java è che non permette di gestire molte eccezioni diverse allo stesso modo, e questo riduce la produttività e allunga il codice da scrivere. c'è anche da dire che il team di C# ha "risolto" la cosa in un modo che non mi piace, ovvero tutte le eccezioni sono unchecked. ma dico io, ci vuole tanto a definire un linguaggio dove l'istruzione catch prende una lista di eccezioni anziché un'eccezione sola?

edit - aggiungo anche: una delle prime cose che mi ha detto il tipo che mi sta seguendo nella tesi è che lo strato di software che io sto sviluppando deve avere una casistica d'errore semplice: non devo mettermi a lanciare una dozzina di eccezioni da ogni metodo (ce ne sarebbero a volontà visto che devo comunicare con due database di tipo diverso, uno MySQL e l'altro LDAP), ma mi ha detto di scrivere solo 4 eccezioni:

SystemException - per tutti i gli errori locali (ad es., non trovo un file di inizializzazione, oppure è corrotto)
NetworkException - per problemi di rete (es. mia sorella inciampa nel cavo ethernet :asd: )
SecurityException - per gli access check falliti (es., non ho i permessi per scrivere alcuni dati sul database)
DataException - i dati su uno dei due database sono corrotti

praticamente mi sta facendo eliminare manualmente il problema della numerosità delle eccezioni. e già 4 eccezioni sono tante: sono tutte checked perché tutte quante rappresentano condizioni di errore incontrollabili dal programma (notare gli esempi che ho fatto), quindi significa che ogni singola chiamata alla libreria che sto sviluppando dovrà essere circondata da ben 4 catch, a meno che qualcuna delle 4 eccezioni non venga propagata; e non c'è altra soluzione! figuriamoci se le propagavo tutte direttamente senza suddividerle per argomento: erano una dozzina di catch a chiamata.

cdimauro
10-08-2008, 18:58
non c'è motivo ma mi pare che non ci sia neanche problema; anzi, (leggi sotto)

appunto, quindi hanno fatto contenti tutti; che problema c'è? :D
Perché aumenta inutilmente la complessità del linguaggio, e il numero di cose che bisogna conoscere.

Ecco qua: http://www.netfunny.com/rhf/jokes/99/Nov/perl.html

in particolare: "more than one way to do it..."

Inoltre:
>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
:cool:
e sennò come lo inserisci il codice in mezzo all'HTML? oppure intendi che devono cominciare con quel tag anche i programmi standalone, non mischiati all'HTML? :D
in questo secondo caso è pazzesco :asd:
La seconda che hai detto. :asd: :asd: :asd:
Metto le mani avanti dicendo che a prescindere da questo mi sta facilitando parecchio la vita (insieme col Python, per la gioia di cdimauro ;) )
E' cosa buona e giusta. :p
ma dico io, ci vuole tanto a definire un linguaggio dove l'istruzione catch prende una lista di eccezioni anziché un'eccezione sola?
In effetti non ci vuole molto. Basta andare qui: www.python.org e lo trovi. :cool:

nico159
10-08-2008, 22:52
Sbaglio o manca visual basic? :sofico:

cdimauro
10-08-2008, 23:42
Aggiungilo tu. :)

Penso di aver finito con PHP. Al momento c'è molta più roba per PHP che per tutti gli altri linguaggi messi assieme. :asd:

Enjoy. :D

Ho anche approfittato per mettere un paio di cosucce su Java. :cool:

||ElChE||88
11-08-2008, 00:19
Al momento c'è molta più roba per PHP che per tutti gli altri linguaggi messi assieme. :asd:
Visto il livello di PHP direi che è giusto così. :asd:

71104
12-08-2008, 11:15
Perché aumenta inutilmente la complessità del linguaggio, e il numero di cose che bisogna conoscere. aumenta la complessità del linguaggio di uno sputo, e non inutilmente: fa contemporaneamente felici più persone allo stesso tempo. ed inoltre non aumenta la quantità di cose che devi conoscere: tu i commenti li scrivi in una sola maniera, quella che più ti aggrada. :Prrr:


La seconda che hai detto. :asd: :asd: :asd: minchia :asd:


In effetti non ci vuole molto. Basta andare qui: www.python.org e lo trovi. :cool: :mc:


PS: ho rimpinguato un po' la sezione sul C++ :read:

Hiskrtapps
12-08-2008, 13:26
se posso permettermi, non di criticare ma di provare a integrare alcuni commenti riguardanti php (su cui concordo al 99%)

if you send the wrong number of arguments to a function call, no error is raised; the extra arguments are ignored.
L'errore esiste ed è sollevato, dipende dagli errori che TU decidi reputare bloccante o no.
L'appunto che si può fare è che esistono modi diversi di giudicare gli errori e questi sono dipendenti da scelte del programmatore: che succede se qualcuno usa qualcosa realizzato da qualcun'altro, e quindi con premesse diverse? Potrei avere errori inattesi (perchè la gestione dell'errore mia è diversa dalla tua che hai sviluppato il modulo che uso)

there are two ways for end-of-line comments: // and #
anche in java puoi mettere i commenti in 2 modi: // /* e anche /**

code must be inserted between <?php and ?> tags
per separarlo dall'html, scelta saggia; lo fa anche asp e jsp.
al massimo si può dire: perchè esistono 2 start tag: <? <?php, ma dire che non servono direi che non ha senso

constants do not use $ prefix, such as variables
e quindi?

static variables cannot be accessed from an instance; they must be
accessed using the $class::variable scope operator
questa non l'ho capita. anche per accedere a una proprietà dell'oggetto in cui ti trovi devi sempre mettere $this-> davanti

ndakota
12-08-2008, 13:42
there are two ways for end-of-line comments: // and #
anche in java puoi mettere i commenti in 2 modi: // /* e anche /**


penso che intendano commenti di riga singola. In Java // è un commento end-of-line, /* questo multiriga e questo /** per la Javadoc se non erro. Hanno tutti una loro utilità.

EDIT: abitiamo a 10 minuti di distanza :eek:

Hiskrtapps
12-08-2008, 13:56
penso che intendano commenti di riga singola. In Java // è un commento end-of-line, /* questo multiriga e questo /** per la Javadoc se non erro. Hanno tutti una loro utilità.

EDIT: abitiamo a 10 minuti di distanza :eek:
se sei di milano città direi di si :-D

Per quanto riguarda il javadoc nessuno vieta di creare qualcosa di analogo per php (esiste già phpDoc in realtà) che interpreti i diversi tipi di commento in modo diverso.
e cmq in java nessuno mi vieta di mettere un commento singola riga così /* */
ma prima era stato fatto notare questo principio
There should be one-- and preferably only one --obvious way to do it.

in cui anche io credo, solo che così come sono scritte sembra che certe cose e certe scelte sbagliate siano solo di php, e se per la maggior parte delle cose può anche essere così, non lo è per tutte

cdimauro
12-08-2008, 14:26
aumenta la complessità del linguaggio di uno sputo, e non inutilmente: fa contemporaneamente felici più persone allo stesso tempo. ed inoltre non aumenta la quantità di cose che devi conoscere: tu i commenti li scrivi in una sola maniera, quella che più ti aggrada. :Prrr:
Sì, ma il linguaggio è comunque più complesso. Poi immagina di estendere questo principio in generale: per accontentare tutti il PHP diventerebbe un porcaio (vabbé, lo è già abbastanza, ma... non c'è limite alle zozzerie che si possono aggiungere :asd:).

Esempio: ma perché non mettiamo le stringhe multilinea come in Python. Ah, visto che ci siamo, mettiamo anche le n-mila versioni di Ruby. Ecc. ecc. ecc.

Accontentare tutti = realizzare un linguaggio di programmazione senza una sua identità e aumentando inutilmente (perché non sono state introdotte nuove funzionalità effettivamente, ma nuove modalità per esprimere gli stessi concetti) la sua complessità.

Il tutto IMHO ovviamente. :)
:mc:
E lasciamo fanboyeggiare ogni tanto, dai. :p
PS: ho rimpinguato un po' la sezione sul C++ :read:
Benissimo, ma non ho tempo di leggere al momento: sto scappando qualche giorno per le ferie. :D Me le godrò con calma dopo. ;)

P.S. Agli altri messaggi risponderò al ritorno. :)

ndakota
12-08-2008, 15:09
se sei di milano città direi di si :-D


no molto più vicino.. pioltello :p

vladix
12-08-2008, 15:45
if you send the wrong number of arguments to a function call, no error is raised; the extra arguments are ignored.
c'avrei giurato di aver visto questa riga nella sezione dedicata al javascript :confused:

EDIT:


code must be inserted between <?php and ?> tags
per separarlo dall'html, scelta saggia; lo fa anche asp e jsp.
al massimo si può dire: perchè esistono 2 start tag: <? <?php, ma dire che non servono direi che non ha senso

c'e anche "<% %>" e "<script language='PHP'></script>" :asd:

RaouL_BennetH
12-08-2008, 16:10
Io aggiungerei anche Visual Basic.

Il perchè è semplice:

permette a persone come me di scrivere programmi che funzionano :cool: :D

sottovento
12-08-2008, 16:16
.
tuttavia è anche vero quello che il team di C# ha risposto a Bruce Eckel nell'intervista (vedi qua: http://www.artima.com/intv/handcuffs.html), ovvero che certe volte il numero di possibile eccezioni (checked, aggiungo io) che un pezzo di codice potrebbe lanciare è spropositato, e chi usa quel pezzo di codice fa un banale "catch (Exception e)" e le gestisce tutte allo stesso modo; un difetto di Java è che non permette di gestire molte eccezioni diverse allo stesso modo, e questo riduce la produttività e allunga il codice da scrivere. c'è anche da dire che il team di C# ha "risolto" la cosa in un modo che non mi piace, ovvero tutte le eccezioni sono unchecked. ma dico io, ci vuole tanto a definire un linguaggio dove l'istruzione catch prende una lista di eccezioni anziché un'eccezione sola?

Sono d'accordo.
Ho riletto diverse volte il "pensiero" di Bruce Eckel e non riesco a capire come le unchecked exceptions possano essere un vantaggio (per lo meno, come possano risolvere questo problema).

A dire il vero, lui insisteva molto sulle eccezioni "ingoiate" (swallow), vale a dire "tappate" dal programmatore pigro o poco accorto, ma non mi sembra abbia dato una spiegazione valida: per quale motivo le eccezioni unchecked non soffrono del suddetto problema.

Visto che ci siamo, ecco qui una chicca fresca fresca:
E' tutto il giorno che sto litigando perche' il programma scritto dal cliente (in C++ sotto Visual) va in crash senza motivo.
Dopo aver analizzato la situazione col debugger, e' chiaro che veniva sollevata un'eccezione da qualche funzione. Quale funzione e che tipo di eccezione? Non era chiaro, c'e' voluto un bel po' per trovarla.

Ed ora? Come faccio a sapere se le ho prese tutte?

La tentazione e' quella di scrivere, nel punto piu' "alto" possibile nel codice, un bel catch (...). Purtroppo non avrebbe senso, non mi riporterebbe le informazioni necessarie a fare il recovery della situazione e...



try
{
char *p = NULL;

*p = 'a';
}
catch (...)
{
printf ("Eccezione\n");
}



Quindi, nel caso mettessi quel catch(...), l'applicazione non mi crasherebbe piu'! O meglio, prima o poi andra' in crash ma non sara' piu' possibile trovarlo facilmente....

71104
12-08-2008, 21:13
giusto! aggiornato con: "catch (...) doesn't allow to know the type of exception."

sottovento
13-08-2008, 09:12
Ok, ma la mia intenzione era quella di aprire un flame (beh, non proprio): perche' la checked exception sono da considerarsi il male della Terra? Perche' addirittura sono da considerarsi anti-pattern?
Perche' su Internet si leggono cose del tipo "l'esperimento delle checked-exception fatto da Sun con Java e' da dichiararsi fallito?".

Continuo a leggere pagine e pagine di materiale contro le checked exception e nessuno che riesca a convincermi.... qualcuno riesce ad illuminarmi?

Lo so che questo non e' proprio il thread giusto, ma visto che si parla di linguaggi che fanno schifo...qual e' la cosa migliore? Checked o Unchecked?

astorcas
13-08-2008, 10:52
Ok, ma la mia intenzione era quella di aprire un flame (beh, non proprio): perche' la checked exception sono da considerarsi il male della Terra? Perche' addirittura sono da considerarsi anti-pattern?
Perche' su Internet si leggono cose del tipo "l'esperimento delle checked-exception fatto da Sun con Java e' da dichiararsi fallito?".

Continuo a leggere pagine e pagine di materiale contro le checked exception e nessuno che riesca a convincermi.... qualcuno riesce ad illuminarmi?

Lo so che questo non e' proprio il thread giusto, ma visto che si parla di linguaggi che fanno schifo...qual e' la cosa migliore? Checked o Unchecked?

Personalmente sento la mancanza delle checked in C#, e tra l'altro ho letto (cosa che non mi è capitata con Java) sorgenti scritti da altri dove le eccezioni sono diventate così "leggere" che i try catch hanno sostituito gli if else.....
Se proprio devo obiettare su qualcosa mi viene da pensare: "Perchè diamine le unchecked exception che derivano sempre RuntimeException sono sottoclassi di Exception da cui derivano tutte le eccezioni checked?" sta cosa non la capisco.

71104
13-08-2008, 11:01
Se proprio devo obiettare su qualcosa mi viene da pensare: "Perchè diamine le unchecked exception che derivano sempre RuntimeException sono sottoclassi di Exception da cui derivano tutte le eccezioni checked?" sta cosa non la capisco. quoto!! questa ce la metto subito, anche io ho sempre pensato che dovesse essere casomai il contrario, cioè Exception che deriva da RuntimeException (con altri nomi ovviamente).

edit - aggiornata; grazie astorcas.

sottovento
13-08-2008, 11:14
Personalmente sento la mancanza delle checked in C#, e tra l'altro ho letto (cosa che non mi è capitata con Java) sorgenti scritti da altri dove le eccezioni sono diventate così "leggere" che i try catch hanno sostituito gli if else.....
Se proprio devo obiettare su qualcosa mi viene da pensare: "Perchè diamine le unchecked exception che derivano sempre RuntimeException sono sottoclassi di Exception da cui derivano tutte le eccezioni checked?" sta cosa non la capisco.

Quindi sei anche tu a favore. Proprio non capisco, e soprattutto perche' dovrebbe essere un anti-pattern!?!?
Sto cercando di capire il punto di vista di chi sostiene che siano un esperimento fallito, ma proprio non ci riesco... non riesco a vedere un solo vantaggio delle unchecked :mc:

71104
13-08-2008, 11:36
Quindi sei anche tu a favore. Proprio non capisco, e soprattutto perche' dovrebbe essere un anti-pattern!?!?
Sto cercando di capire il punto di vista di chi sostiene che siano un esperimento fallito, ma proprio non ci riesco... non riesco a vedere un solo vantaggio delle unchecked :mc: intendiamoci... servono entrambe, sia le checked sia le unchecked. è inutile mettersi a catchare tutte le possibili NullPointerException.

sottovento
13-08-2008, 13:13
intendiamoci... servono entrambe, sia le checked sia le unchecked. è inutile mettersi a catchare tutte le possibili NullPointerException.

D'accordissimo. Ma e' anche vero che le NullPointerException & affini si possono benissimo chiamare "Errori di programmazione".
Pertanto nel 90% dei casi la cosa migliore e' terminare l'applicazione (o terminare semplicemente l'operazione in corso), magari dopo aver raccolto i dati per risolvere il problema.
Penso sia un caso diverso. Il fatto che un'eccezione simile possa essere catchata e' solo per avere la possibilita' di produrre una diagnostica, o poco piu'. Anche perche', a seguito di un errore simile (mi riferisco principalmente al C++, ma anche Java potrebbe esserne affetto) lo stato dell'applicazione potrebbe essere non noto. Insomma, l'applicazione potrebbe diventare instabile ed andare in crash in un altro punto, ben lontano da dove c'e' il bug.

Trovare un errore simile, a questo punto, e' impresa ardua.

Esempio: in Visual C++:


class MyTest
{
private:
char name[100];

public:
MyTest (char *str)
{
strcpy (name, str);
printf ("MyTest(%s) - constructor\n", name);
}

~MyTest ()
{
printf ("MyTest(%s) - destructor\n", name);
}
};

void f1 () throw()
{
MyTest v1("v1");
MyTest v2("v2");
MyTest v3("v3");
MyTest v4("v4");
MyTest v5("v5");

char *p = NULL;
*p = 'a';
}

int main(int argc, char* argv[])
{
try
{
f1 ();
}
catch (...)
{
printf ("Eccezione\n");
}
printf ("Ora continuo normalmente con la mia applicazione\n");
...
}


Ho aggiunto throw() solo per peggiorare la situazione, se anche lo si toglie si ha comunque un bel casino.

Personalmente, non me la sentirei di proseguire l'esecuzione dopo un errore di questo genere.... raccoglierei i dati di log, farei il dump dello stack e goodbye.

71104
13-08-2008, 13:52
in Java è diverso: Java è una piattaforma managed, non esistono buffer overflows e non esistono dangling pointers o altre amenità; se ottieni una NullPointerException l'unico problema è che hai dereferenziato un riferimento nullo, per il resto lo spazio di memoria del tuo programma è a posto e se catturi la NullPointerException puoi continuare normalmente.

mi viene in mente il comportamento di alcuni strumenti di refactoring di Eclipse: sporadicamente qualche refactoring fallisce e ti viene mostrato un messaggio coi dettagli sull'eccezione che ti permette di fare il rollback del refactoring, di abortirlo brutalmente, o di ignorare il problema; qualsiasi cosa tu scelga puoi comunque continuare a usare Eclipse senza problemi, anche se quello strumento di refactoring era buggato.

sottovento
13-08-2008, 17:43
Visto che parliamo di linguaggi che fanno schifo e che sto lavorando su codice C++ altrui: si potrebbe aggiungere che esiste una legge non scritta sull'implementazione dei distruttori.
La regola e': i distruttori non possono sollevare eccezioni, pena memory leak non eliminabili.
Non male, vero? Si puo' aggiungere? Il linguaggio non vieta di scrivere distruttori che sollevano eccezioni, ma poi sono fatti tuoi...

marco.r
13-08-2008, 17:57
Lo permette perche' nessuno ti vieta di invocare costruttori e distruttori senza allocare/deallocare memoria (lo fa anche la libreria standard del C++) e quindi in quel caso potresti pure lanciarle le eccezioni.
Detto questo, se un mio collega osasse scrivere una classe pensata per essere usata solo in quei contesti e che pure mi lanci eccezioni nel distruttore probabilmente lo prenderei a schiaffoni :D :p

sottovento
13-08-2008, 18:05
Lo permette perche' nessuno ti vieta di invocare costruttori e distruttori senza allocare/deallocare memoria (lo fa anche la libreria standard del C++) e quindi in quel caso potresti pure lanciarle le eccezioni.
Detto questo, se un mio collega osasse scrivere una classe pensata per essere usata solo in quei contesti e che pure mi lanci eccezioni nel distruttore probabilmente lo prenderei a schiaffoni :D :p

Purtroppo nel mio caso si chiama cliente, non collega, ed ovviamente ha ragione lui ("Oh! ma che bel software, come funzione bene! Ha qualche piccolo problema, va in crash ogni tre minuti ma non e' importante).

Detto questo, visto quant'e' bello il c++ si puo' giocare anche piu' sporco: cosa ne dici di throw() di classi che potenzialmente possono sollevare eccezioni (magari, per semplificarci la vita, potrebbero sollevarle nel costruttore di copia).

E' un capolavoro! Anche perche' spesso e' difficile realizzare se potrebbe essere sollevata un'eccezione proprio nella gestione delle eccezioni!!
In tal caso... ciao pep!

Un esempio:


throw (string("quando si e' sottovento si chiama"))


In generale, queste sono le cose che si frappongono fra me e la pensione.

sottovento
14-08-2008, 11:21
Altra benzina sul fuoco: anche Google decide di NON usare le eccezioni di C++ poiche' son piu' problemi che vantaggi:

http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Exceptions

(immagino che questo link sia vecchio, ma sono vecchio anch'io quindi siam pari)

marco.r
14-08-2008, 13:45
Detto questo, visto quant'e' bello il c++ si puo' giocare anche piu' sporco: cosa ne dici di throw() di classi che potenzialmente possono sollevare eccezioni (magari, per semplificarci la vita, potrebbero sollevarle nel costruttore di copia).

Beh, basta non lanciare eccezioni che possano lanciarne altre :p, tipicamente si tratta di classi ad hoc per cui non vedo grossi problemi.
bad_alloc e' un caso particolare perche' comunque puoi fare ben poco: tipicamente il tuo programma si pianta ben prima perche' fa trashing sullo swap file. E qualora tu veramente finisca la memoria probabilmente c'e' anche un processo che la sta succhiando tutta, per cui prima o poi probabilmente sara' il S.O. ad uccidere il tuo programma.
In casi particolari puoi sempre decidere di allocare preventivamente l'oggetto e lanciarne un riferimento.

DanieleC88
14-08-2008, 13:52
tipicamente si tratta di classi ad ok
:doh:
Ad hoc (http://it.wikipedia.org/wiki/Ad_hoc)! :D

marco.r
14-08-2008, 14:01
:doh:
Ad hoc (http://it.wikipedia.org/wiki/Ad_hoc)! :D

Sorry per il lapsus. Ormai sostituisco parole in inglese dappertutto (non hai idea quante volte scriva "server" invece che "serve" :D )

DanieleC88
14-08-2008, 14:14
LOL! Ma figurati, è solo che io sono troppo pignolo per non notare una svista così. :D

71104
14-08-2008, 14:24
Sorry per il lapsus. Ormai sostituisco parole in inglese dappertutto (non hai idea quante volte scriva "server" invece che "serve" :D ) calcola che io al posto tuo avrei scritto: non hai idea di quante volte scriva "server" invece che "server" :asd:

71104
14-08-2008, 14:31
edit - scusate ho scritto una cavolata :D

ari-edit - e invece no, aveva senso :O
riscrivo tutto :Prrr:

riflettendo sulle eccezioni unchecked mi è venuto in mente un nuovo punto da mettere nel paragrafo Java sucks. riprendendo il discorso di andbin:

Una eccezione come FileNotFoundException è checked perché il fatto che un file non esiste è una situazione che può accadere in un mondo "reale", es. un utente ha indicato un nome di file non presente. Quindi il non aver trovato un file non denota un "baco" del programma e pertanto tale situazione deve essere presa in considerazione.

Se invece salta fuori un ArrayIndexOutOfBoundsException o un NullPointerException o un ClassCastException (tutte "unchecked"), quasi certamente è dovuto ad un "baco" del programma. Cioè è il programmatore che ha sbagliato ad usare metodi, variabili, costrutti o altro (magari anche solo perché non ha letto bene la documentazione di un metodo).
d'accordissimo, ma allora come mai la SecurityException (http://java.sun.com/javase/6/docs/api/index.html?java/lang/SecurityException.html) è unchecked? un programmatore non può mica sapere a priori come si comporta il SecurityManager.

gugoXX
14-08-2008, 14:44
Ciao, ho un altro sucks del C#, che secondo me prima o poi si paghera'.
Esistono i Funzionali, che sono praticamente puntatori a funzione del C++, come dei delegate, fortemente tipizzati e con codice scritto immediatamante.
Se voglio descrivere un funzionale che accetta in input una stringa e ne restituisce il quadrato della lunghezza, posso scrivere

Func<string, int> fnlen2 = str=>str.Length*str.Length;
per poi usarlo in seguito cosi'
int tl = fnlen2("pippo");


Se volessi definire un Funzionale che accetta piu' parametri, per restituire un double, scriverei cosi'

// Funzionale che accetta un stringa e un intero e restituisce un double
Func<string,int, double> fns = (t,u) => (double)t.Length/(double)u;


Ebbene. Potrebbe essere utile talvolta avere un Funzionale che esegue qualcosa e non restituisce nulla
Potrei essere tentato di scrivere

// funzionale che, accettata in input una stringa, la stampa sullo schermo
Func<string,null> Exec = str=>Console.WriteLine(str);
oppure
Func<string,void> Exec = str=>Console.WriteLine(str);
//Per usarla cosi'
Exec("Pippo");


Ebbene. non si puo'.
Il funzionale particolare senza output non si dichiara con Func, ma si dichiara con Action


Action<string> Exec = str=>Console.WriteLine(str);
...
Exec("Pippo");


E secondo me prima o poi si paghera'.

DanieleC88
14-08-2008, 14:51
E secondo me prima o poi si paghera'.
Perché lo pensi? Intendo, sono d'accordo anch'io che magari un funzionale poteva essere definito con un valore void di ritorno o poteva anche restituire un qualsiasi valore (come un intero) che ignori perché non ti serve, ma se c'è un metodo per definirli alternativamente (Action) non è lo stesso?

71104
14-08-2008, 14:51
vabbè, ma devi anche spiegarci il perché :D

71104
14-08-2008, 14:52
Perché lo pensi? ecco appunto :Prrr:

DanieleC88
14-08-2008, 15:04
Mi spiego meglio: spesso in C ho fatto funzioni tipo:
int f()
{
/* ... */
return 0;
}
Chiamandole poi con una cosa tipo:
f();
Quindi semplicemente scartando del tutto il valore risultante. Non si può fare una cosa del genere mi stai dicendo? :)

Cioè, se io scrivo una funzione che restituisce un void non posso wrapparla con un funzionale ma con un action per forza? A parte la scomodità della duplicazione, qual'è lo svantaggio pratico?

ciao ;)

gugoXX
14-08-2008, 15:50
Dunque, provo a scrivere quello che ho in testa, non e' semplicissimo.

Innanzitutto per poter eserguire una funzione in C# (ma anche in C++, e anche in C), indipendentemente dal fatto che venga o meno restituito un risultato, e' sufficiente lanciarla con i parametri, ignorando il risultato che puo' non servire.
Es: Voglio costruire una funzione che accetti una stringa, la stampi e restituisca il numero di spazi trovati dentro la stringa.

public static int StampaEDimmiQuantiSpazi(string input)
{
Console.WriteLine(input);
int ret = input.ToCharArray().Count(ch => ch == ' ');
return ret;
}
Ora, questa funzione posso richiamarla cosi' com'e', quando mi dovesse servire semplicemente stampare a video, ignorando il valore di ritorno che di fatto non mi interessa

string str = "La mia ragazza mi ha preparato il profiterolles";
StampaEDimmiQuantiSpazi(str);

Ignorando di fatto il valore 7 che viene restituito.

Ora si entra un po' nei funzionali.
I funzionali cosi' come li ho scritti prima non servono a nulla. I funzionali servono quando ho bisogno di passare "del codice" ad una funzione, per farci qualcosa.
Ad esempio, mi potrebbe venire in mente di costruire una funzione che, accettato in ingresso una enumerazione (es. un array) e un funzionale, esegua il funzionale per tutti gli elmenti dell'enumerazione.
In realta' mi interessa eseguire il funzionale, indipendentemente dal suo ipotetico valore di ritorno, questo perche' in realta' a me serve la parte attiva dell'operazione, non il suo ritorno.
Tale funzione (metodo) risulterebbe cosi':

public static void ForAll<T, U>(IEnumerable<T> Domain, Func<T, U> exec)
{
foreach (T t in Domain) exec(t);
}


E potrei usarla, con la funzione di prima, in un caso come questo

static void Main(string[] args)
{
List<string> strs=new List<string>(){"Pio pio","Ninna nanna bel bambino","Quippe Utopote Praesertim"};

ForAll<string,int>(strs, StampaEDimmiQuantiSpazi);
}

Che si legge:
1. Costruisco una lista di 3 stringhe.
2. detti string,int rispettivamente il tipo dell'enumerazione e il valore di ritorno dell'operazione da eseguire, per ciascuna stringa dell'enumerazione voglio eseguire quell'operazione, che stampa e restituisce appunto un int
Ignorando di fatto il valori di ritorno del funzionale, rispettivamente 1,3,2

Anzi, non solo ignorando il valore di ritorno, ma bensi' ignorando in realta' anche il tipo del valore di ritorno (int).
La funzione ForAll funziona con qualsiasi tipo di valori di ritorno di un qualsiasi ipotetico funzionale che deve accettare, in input il tipo dell'enumerazione, e in output quello che vuole.
L'unico "constraint" e' che il tipo dell'enumerazione sia lo stesso tipo di ingresso del funzionale.
Voglio infatti eseguire quell'operazione per ciascun elemento dell'enumerazione, e ovviamente il funzionale deve accettare un valore di quel ben specifico tipo, e lo potro' usare quindi solo funzioni che accettano in ingresso quel tipo.
Potrebbe essere una lista di double, e la funzione potrebbe essere un'operazione che accettato un double crea un colore componente di grigio con quel valore, colora un'area con quel grigio e restituisce una stringa che e' il "Nome del colore HTML Standard" piu' vicino a quello creato.
Per ciascuno dei double si voglia eseguire il funzionale.
La funzione ForAll<double,string> di prima andrebbe tanto bene.


Ebbene, tutto cio' vale tranne che per il caso in cui l'operazione da eseguire ritorni void, ovvero non ritorni nulla.
Es: La funzione Console.WriteLine (che e' standard), accetta in ingresso qualcosa, lo stampa, e non ritorna nulla (void)
Per questo, e solo per questo specifico caso non potro' scrivere infatti

static void Main(string[] args)
{
List<string> strs=new List<string>(){"Pio pio","Ninna nanna bel bambino","Quippe Utopote Praesertim"};

//ForAll<string,int>(strs, StampaEDimmiQuantiSpazi);

ForAll<int,void>(strs, Console.WriteLine);
}


Per poter sfruttare tale dinamicita' sono costretto a definire un altro overload di ForAll, per il solo caso in cui il valore di ritorno del funzionale non sia un tipo qualsiasi, ma sia il tipo particolare void (che appunto in C# non e' un tipo)

Il tutto sara' quindi:

static class Program
{
static void Main(string[] args)
{
List<string> strs=new List<string>(){"Pio pio","Ninna nanna bel bambino","Quippe Utopote Praesertim"};

ForAll<string,int>(strs, StampaEDimmiQuantiSpazi);

ForAll<string>(strs, Console.WriteLine);
}

public static int StampaEDimmiQuantiSpazi(string input)
{
Console.WriteLine(input);
int ret = input.ToCharArray().Count(ch => ch == ' ');
return ret;
}


public static void ForAll<T, U>(IEnumerable<T> Domain, Func<T, U> exec)
{
foreach (T t in Domain) exec(t);
}

public static void ForAll<T>(IEnumerable<T> Domain, Action<T> exec)
{
foreach (T t in Domain) exec(t);
}
}


Secondo me prima o poi si paghera'.
Magari la prossima volta che vorranno estendere la parte funzionale con qualcosa di piu'.

astorcas
14-08-2008, 17:39
Dunque, provo a scrivere quello che ho in testa, non e' semplicissimo.
....
Secondo me prima o poi si paghera'.
Magari la prossima volta che vorranno estendere la parte funzionale con qualcosa di piu'.

Cazzarola c'ho mezzo mezz'ora a capire dove stava il problema... ora ho capito che hai la palla di cristallo e leggi il futuro :asd:

Scherzi a parte ho colto il punto ;)

cdimauro
14-08-2008, 22:16
se posso permettermi, non di criticare ma di provare a integrare alcuni commenti riguardanti php (su cui concordo al 99%)
Le critiche sono sempre ben accette se costruttive, e inoltre qui nessuno è nato col dono dell'infallibilità. :)

Io, come gli altri, ho espresso soltanto le mie opinioni, e se sono errate non vedo perché non dovrei cambiare idee e la relativa paginetta su quel wiki. :p
if you send the wrong number of arguments to a function call, no error is raised; the extra arguments are ignored.
L'errore esiste ed è sollevato, dipende dagli errori che TU decidi reputare bloccante o no.
Non mi sembra sia così. Ecco qui: http://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list

"PHP 4 and above has support for variable-length argument lists in user-defined functions. This is really quite easy, using the func_num_args(), func_get_arg(), and func_get_args() functions.

No special syntax is required, and argument lists may still be explicitly provided with function definitions and will behave as normal."

Se una caratteristica del linguaggio può sollevare eccezioni, in genere è segnalato. Non mi pare questo il caso. ;)
L'appunto che si può fare è che esistono modi diversi di giudicare gli errori e questi sono dipendenti da scelte del programmatore: che succede se qualcuno usa qualcosa realizzato da qualcun'altro, e quindi con premesse diverse? Potrei avere errori inattesi (perchè la gestione dell'errore mia è diversa dalla tua che hai sviluppato il modulo che uso)
Vero, ma, ripeto, non è questo il caso, documentazione del linguaggio alla mano.

Poi se mi stai dicendo che il passaggio di un numero di argomenti superiore a quello previsto può generare o meno warning o eccezioni, allora ti pregherei di darmi qualche informazione ufficiale in merito in modo da... aggiungere un'altra nota di demerito per il PHP. :asd:
there are two ways for end-of-line comments: // and #
anche in java puoi mettere i commenti in 2 modi: // /* e anche /**
Ha ragione ndakota. ;)
code must be inserted between <?php and ?> tags
per separarlo dall'html, scelta saggia; lo fa anche asp e jsp.
al massimo si può dire: perchè esistono 2 start tag: <? <?php, ma dire che non servono direi che non ha senso
Qui ti sei perso qualche messaggio con Alberto in cui abbiano discusso dell'argomento in questione. :)

I tag in questione hanno senso... all'interno di una pagina HTML, e questa è la strada seguita da tutti i linguaggi di programmazione che si possono usare nel templating di codice HTML, XHTML, XML o altro.

Non hanno senso se sto sviluppando un'applicazione NON di templating.

Per essere chiari, se scrivo questo codice Python:
print 'Hello, world!'
in un'applicazione NON di templating, lo scriverò... esattamente così, quindi senza alcun tag.

Se invece lo voglio scrivere in un'applicazione di templating e sto usando, per esempio, mod_python sfruttando la funzionalità PSP (http://www.modpython.org/live/current/doc-html/pyapi-psp.html) quel codice lo scriverò così:
<%
print 'Hello, world!'
%>
;)

L'assurdità, con PHP, è che perfino gli include file debbono avere questi tag.

Cioé: io sto eseguendo codice PHP (quindi sono già DENTRO questi tag), metto un'istruzione include pippo.php, e pippo.php DOVRA' avere anch'esso questi tag all'interno. Assolutamente ridicolo.
constants do not use $ prefix, such as variables
e quindi?
Il modello non è omogeneo e può portare facilmente a errori. Ad esempio capita di scrivere costanti così:
$PI = 3.14;
Salvo poi pensare che sono costanti e referenziarle così:
$A = 2 * PI;
e viceversa ovviamente (usare define per definire PI e referenziarla con $PI).

Avrebbero potuto utilizzare una sola sintassi per costanti e variabili, e provvedere alla "blindatura" delle prime soltanto in fase di scrittura.
static variables cannot be accessed from an instance; they must be
accessed using the $class::variable scope operator
questa non l'ho capita. anche per accedere a una proprietà dell'oggetto in cui ti trovi devi sempre mettere $this-> davanti
Non sempre. Se hai definito un attributo come "statico" non puoi usare l'operatore ->.

Sempre dal manuale di PHP (http://www.php.net/manual/en/language.oop5.static.php):

"Static properties cannot be accessed through the object using the arrow operator ->."

Dall'esempio è tutto più chiaro:
class Foo
{
public static $my_static = 'foo';

public function staticValue() {
return self::$my_static;
}
}

class Bar extends Foo
{
public function fooStatic() {
return parent::$my_static;
}
}


print Foo::$my_static . "\n";

$foo = new Foo();
print $foo->staticValue() . "\n";
print $foo->my_static . "\n"; // Undefined "Property" my_static
Come vedi non funziona. Per accedere a my_static devi far ricorso all'operatore di scope:
print $foo::$my_static . "\n";
Il che, ancora una volta, mi sembra assolutamente ridicolo: my_static, sia esso statico o meno, è comunque un attributo della classe Foo e, come tale, dovrebbe essere accessibile dalle istanze sue e delle sue classi derivate esattamente come qualunque altro attributo.

Tra l'altro anche questo può portare facilmente a degli errori. Immagina di aver scritto velocemente il prototipo della tua applicazione e di esserti concentrato esclusivamente sulla risoluzione dei vari problemi.
Il codice funziona, è tutto a posto, e decidi di fare una sana review del codice per ripulirlo, e riorganizzarlo rifattorizzandolo.
Ti accorgi che un attributo può essere definito statico e gli aggiungi la parolina "static" per definirlo tale. A questo punto se di PHP conosci vita morte e miracoli comprese tutte le sue magagne (che sono tonnellate, come si può vedere dal wiki), vai a vedere in tutte le parti del codice dove referenzi quest'attributo e rimpiazzi -> con ::.
Se sei meno pratico del linguaggio sei... fottuto: il tuo codice non funzionerà più, e te ne accorgerai... in produzione.
Per quanto riguarda il javadoc nessuno vieta di creare qualcosa di analogo per php (esiste già phpDoc in realtà) che interpreti i diversi tipi di commento in modo diverso.
e cmq in java nessuno mi vieta di mettere un commento singola riga così /* */
Certo che lo puoi fare, ma... questo è un ALTRO tipo di commento. Ha una funzionalità diversa per cui è stato concepito: quella di racchiudere blocchi di codice.

Poi puoi usarlo anche per i commenti di fine riga, non c'è problema, ma sarebbe come scomodare un cannone per sparare a una mosca. :D
ma prima era stato fatto notare questo principio
There should be one-- and preferably only one --obvious way to do it.

in cui anche io credo, solo che così come sono scritte sembra che certe cose e certe scelte sbagliate siano solo di php, e se per la maggior parte delle cose può anche essere così, non lo è per tutte
Le magagne ci sono anche per gli altri linguaggi: ci mancherebbe! E infatti sono presenti nella pagina.

Semplicemente su PHP erano già tante all'inizio, e si sono moltiplicate coi miei interventi.

Ma nessuno toglie di fare lo stesso con gli altri linguaggi. ;)
c'avrei giurato di aver visto questa riga nella sezione dedicata al javascript :confused:
Aggiungila. :D
Io aggiungerei anche Visual Basic.

Il perchè è semplice:

permette a persone come me di scrivere programmi che funzionano :cool: :D
Aggiungilo. :D
Ciao, ho un altro sucks del C#, che secondo me prima o poi si paghera'.
Esistono i Funzionali, che sono praticamente puntatori a funzione del C++, come dei delegate, fortemente tipizzati e con codice scritto immediatamante.
Se voglio descrivere un funzionale che accetta in input una stringa e ne restituisce il quadrato della lunghezza, posso scrivere

Func<string, int> fnlen2 = str=>str.Length*str.Length;
per poi usarlo in seguito cosi'
int tl = fnlen2("pippo");


Se volessi definire un Funzionale che accetta piu' parametri, per restituire un double, scriverei cosi'

// Funzionale che accetta un stringa e un intero e restituisce un double
Func<string,int, double> fns = (t,u) => (double)t.Length/(double)u;


Ebbene. Potrebbe essere utile talvolta avere un Funzionale che esegue qualcosa e non restituisce nulla
Potrei essere tentato di scrivere

// funzionale che, accettata in input una stringa, la stampa sullo schermo
Func<string,null> Exec = str=>Console.WriteLine(str);
oppure
Func<string,void> Exec = str=>Console.WriteLine(str);
//Per usarla cosi'
Exec("Pippo");


Ebbene. non si puo'.
Il funzionale particolare senza output non si dichiara con Func, ma si dichiara con Action


Action<string> Exec = str=>Console.WriteLine(str);
...
Exec("Pippo");


E secondo me prima o poi si paghera'.
Secondo me manca una sezione "C# sucks because" in quel wiki. :fiufiu: :D

Comunque son d'accordo con te. La trovo una sgradevole asimmetria del linguaggio.

marco.r
14-08-2008, 22:42
Perché lo pensi? Intendo, sono d'accordo anch'io che magari un funzionale poteva essere definito con un valore void di ritorno o poteva anche restituire un qualsiasi valore (come un intero) che ignori perché non ti serve, ma se c'è un metodo per definirli alternativamente (Action) non è lo stesso?

Non e' lo stesso, perlomeno in C# dove, a differenza dei linguaggi funzionali, esiste il tipo void ma non un valore void.
Supponi di voler usare una funzione di mapping da un tipo T ad un tipo U ed applicarla ad un array. Ad esempio potrei applicare ad una serie di float una funzione che mi dice se sono maggiori di 2.0, ed ottenere un array di bool. Ma se applico una funzione non ritorna alcun valore, cosa ottengo ? Se non sbaglio gli array di "void" non esistono in C#, e quindi e' necessaria una distinzione. L'alternativa e' quella di fornire anche un valore void oltre che un tipo.

71104
14-08-2008, 22:49
Secondo me manca una sezione "C# sucks because" in quel wiki. :fiufiu: :D a me piacerebbe tanto se gugoXX la aggiungesse.

DanieleC88
14-08-2008, 22:54
Non e' lo stesso, perlomeno in C# dove, a differenza dei linguaggi funzionali, esiste il tipo void ma non un valore void.
Supponi di voler usare una funzione di mapping da un tipo T ad un tipo U ed applicarla ad un array. Ad esempio potrei applicare ad una serie di float una funzione che mi dice se sono maggiori di 2.0, ed ottenere un array di bool. Ma se applico una funzione non ritorna alcun valore, cosa ottengo ? Se non sbaglio gli array di "void" non esistono in C#, e quindi e' necessaria una distinzione. L'alternativa e' quella di fornire anche un valore void oltre che un tipo.
Scusa, avevo scritto male, io intendevo un tipo void. Nell'esempio che GugoXX ha fatto poco dopo il mio post c'era proprio l'esempio che cercavo: ForAll() è identica per una funzione Tipo A => Tipo B che per una funzione che non restituisca niente: l'unica differenza è nella dichiarazione. A questo punto è ovvio che se io devo processare un'array come mi hai detto poc'anzi non posso assegnare un'array di void in quanto semplicemente non avrebbe senso, ma in quel caso un compilatore dovrebbe essere in grado di saperlo ed evitare quel caso particolare, senza introdurre la duplicazione Func<>/Action<> per distinguerlo dal caso generale.

Non so se mi sono spiegato bene, spesso sono troppo contorto. :D

Hiskrtapps
15-08-2008, 03:46
Non mi sembra sia così. Ecco qui: http://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list

"PHP 4 and above has support for variable-length argument lists in user-defined functions. This is really quite easy, using the func_num_args(), func_get_arg(), and func_get_args() functions.

No special syntax is required, and argument lists may still be explicitly provided with function definitions and will behave as normal."

Se una caratteristica del linguaggio può sollevare eccezioni, in genere è segnalato. Non mi pare questo il caso. ;)

Vero, ma, ripeto, non è questo il caso, documentazione del linguaggio alla mano.

Poi se mi stai dicendo che il passaggio di un numero di argomenti superiore a quello previsto può generare o meno warning o eccezioni, allora ti pregherei di darmi qualche informazione ufficiale in merito in modo da... aggiungere un'altra nota di demerito per il PHP. :asd:

Infatti hai ragione! Correggo il tiro.
Il mio appunto era nato dal fatto che se scrivo qualcosa tipo
print_r("arg1", null, null);
verrà sollevato il seguente errore
print_r() expectes at most 2 parameters, 3 given
quindi in questo caso l'errore c'è, e volendo potrei sopprimerlo o no con l'utilizzo di '@'.
Questo discorso però (facendo qualche prova con php 5), ho visto che non vale per le funzioni (e i metodi di oggetti) definiti dall'utente, quindi effettivamente vale il discorso che hai fatto te.


Qui ti sei perso qualche messaggio con Alberto in cui abbiano discusso dell'argomento in questione. :)

I tag in questione hanno senso... all'interno di una pagina HTML, e questa è la strada seguita da tutti i linguaggi di programmazione che si possono usare nel templating di codice HTML, XHTML, XML o altro.

Non hanno senso se sto sviluppando un'applicazione NON di templating.

Per essere chiari, se scrivo questo codice Python:
print 'Hello, world!'
in un'applicazione NON di templating, lo scriverò... esattamente così, quindi senza alcun tag.

Se invece lo voglio scrivere in un'applicazione di templating e sto usando, per esempio, mod_python sfruttando la funzionalità PSP (http://www.modpython.org/live/current/doc-html/pyapi-psp.html) quel codice lo scriverò così:
<%
print 'Hello, world!'
%>
;)

L'assurdità, con PHP, è che perfino gli include file debbono avere questi tag.

Cioé: io sto eseguendo codice PHP (quindi sono già DENTRO questi tag), metto un'istruzione include pippo.php, e pippo.php DOVRA' avere anch'esso questi tag all'interno. Assolutamente ridicolo.

Ok, quindi comunque dovremmo mantenerli per sviluppare codice di templating. In questo caso mi trovi d'accordo.
Tieni presente però che se creo una pagina pippo.php il fatto che abbia i tag di inizio e fine è coerente con la scelta che hanno preso (che stiamo discutendo).
Io pippo.php devo poterlo includere in altri file php ma devo anche poterlo usare per conto suo, senza che sia incluso, e per questo i tag sono richiesti.


Il modello non è omogeneo e può portare facilmente a errori. Ad esempio capita di scrivere costanti così:
$PI = 3.14;
Salvo poi pensare che sono costanti e referenziarle così:
$A = 2 * PI;
e viceversa ovviamente (usare define per definire PI e referenziarla con $PI).

Avrebbero potuto utilizzare una sola sintassi per costanti e variabili, e provvedere alla "blindatura" delle prime soltanto in fase di scrittura.

Aspè, qui mi sa che avevo inteso una cosa diversa da quella che dici te. Te per costanti intendi quelle che definisci con define?
Io intendevo quelle create con l'utilizzo della parola chiave "const" (e su cui si potrebbe fare un altro discorso lungo una pagina purtroppo)


Non sempre. Se hai definito un attributo come "statico" non puoi usare l'operatore ->.

Sempre dal manuale di PHP (http://www.php.net/manual/en/language.oop5.static.php):

"Static properties cannot be accessed through the object using the arrow operator ->."

Dall'esempio è tutto più chiaro:
class Foo
{
public static $my_static = 'foo';

public function staticValue() {
return self::$my_static;
}
}

class Bar extends Foo
{
public function fooStatic() {
return parent::$my_static;
}
}


print Foo::$my_static . "\n";

$foo = new Foo();
print $foo->staticValue() . "\n";
print $foo->my_static . "\n"; // Undefined "Property" my_static
Come vedi non funziona. Per accedere a my_static devi far ricorso all'operatore di scope:
print $foo::$my_static . "\n";
Il che, ancora una volta, mi sembra assolutamente ridicolo: my_static, sia esso statico o meno, è comunque un attributo della classe Foo e, come tale, dovrebbe essere accessibile dalle istanze sue e delle sue classi derivate esattamente come qualunque altro attributo.

Tra l'altro anche questo può portare facilmente a degli errori. Immagina di aver scritto velocemente il prototipo della tua applicazione e di esserti concentrato esclusivamente sulla risoluzione dei vari problemi.
Il codice funziona, è tutto a posto, e decidi di fare una sana review del codice per ripulirlo, e riorganizzarlo rifattorizzandolo.
Ti accorgi che un attributo può essere definito statico e gli aggiungi la parolina "static" per definirlo tale. A questo punto se di PHP conosci vita morte e miracoli comprese tutte le sue magagne (che sono tonnellate, come si può vedere dal wiki), vai a vedere in tutte le parti del codice dove referenzi quest'attributo e rimpiazzi -> con ::.
Se sei meno pratico del linguaggio sei... fottuto: il tuo codice non funzionerà più, e te ne accorgerai... in produzione.

In java puoi fare quello che dici te, cioè accedere da una istanza di un oggetto a una variabile statica definita dalla classe dell'oggetto stesso, ma è una pratica sconsigliata (tant'evvero che eclipse ti segnala un warning); Classi e oggetti hanno contesti diversi, sinceramente non trovo sbagliato che per accedere a un campo definito dalla classe una istanza debba passare esplicitamente dalla classe stessa (anche se lui stesso è una istanza di quella classe).
Se usassi sempre l'operatore '->' non saresti più in grado, leggendo il codice, di capire se stai accedendo a una variabile della classe o dell'oggetto e sinceramente io credo sia uno svantaggio.

Per quanto riguarda il rifattorizzare direi che è un problema di strumento e molto più generale che questo caso specifico. Uno strumento fatto bene fa sì che in tutte le operazioni di refactoring tutte le reference siano aggiustate (come succede in java usando eclipse) o errori segnalati prima della fase di esecuzione.
Insomma, secondo me questa tua osservazione è quanto meno opinabile e comunque sicuramente non valida in senso assoluto come ben altre evidenze che hai scritto.


Certo che lo puoi fare, ma... questo è un ALTRO tipo di commento. Ha una funzionalità diversa per cui è stato concepito: quella di racchiudere blocchi di codice.

Poi puoi usarlo anche per i commenti di fine riga, non c'è problema, ma sarebbe come scomodare un cannone per sparare a una mosca. :D

No dai, non puoi dire che "/* */" è concepito solo ed esclusivamente per racchiudere blocchi di codice. Non puoi tralasciare il fatto di dover scrivere commenti di più righe che non devono finire nel javadoc.
E di riflesso se uno volesse scrivere commenti su più righe potrebbe benissimo far partire ogni riga con //.
Ci sono diversi modi di scrivere commenti in php come in java...
in java hanno significati diversi solo per come vengono interpretati e in php potrebbe benissimo essere lo stesso.


Le magagne ci sono anche per gli altri linguaggi: ci mancherebbe! E infatti sono presenti nella pagina.

Semplicemente su PHP erano già tante all'inizio, e si sono moltiplicate coi miei interventi.

E vedrai che aumenteranno ancora! Solo basta che non sia per "opinioni"! ;-)

cdimauro
15-08-2008, 07:09
Infatti hai ragione! Correggo il tiro.
Il mio appunto era nato dal fatto che se scrivo qualcosa tipo
print_r("arg1", null, null);
verrà sollevato il seguente errore
print_r() expectes at most 2 parameters, 3 given
quindi in questo caso l'errore c'è, e volendo potrei sopprimerlo o no con l'utilizzo di '@'.
Questo discorso però (facendo qualche prova con php 5), ho visto che non vale per le funzioni (e i metodi di oggetti) definiti dall'utente, quindi effettivamente vale il discorso che hai fatto te.
Sì, esattamente. :)

C'è da dire che print_r è una funzione built-in di PHP, per cui sulla carta dovrebbe comportarsi come qualunque altra funzione, e... non lo fa.

Altro punto di demerito da aggiungere alla pagina. :asd:
Ok, quindi comunque dovremmo mantenerli per sviluppare codice di templating. In questo caso mi trovi d'accordo.
Tieni presente però che se creo una pagina pippo.php il fatto che abbia i tag di inizio e fine è coerente con la scelta che hanno preso (che stiamo discutendo).
Io pippo.php devo poterlo includere in altri file php ma devo anche poterlo usare per conto suo, senza che sia incluso, e per questo i tag sono richiesti.
In tal caso i tag potrebbero essere almeno opzionali. Normalmente un file include... viene incluso e basta, quindi perché portarsi dietro sempre e comunque i tag?
Aspè, qui mi sa che avevo inteso una cosa diversa da quella che dici te. Te per costanti intendi quelle che definisci con define?
Io intendevo quelle create con l'utilizzo della parola chiave "const" (e su cui si potrebbe fare un altro discorso lungo una pagina purtroppo)
No, intendevo quelle definite con define, appunto. :D

Su "const"... scrivi pure, scrivi pure. :D
In java puoi fare quello che dici te, cioè accedere da una istanza di un oggetto a una variabile statica definita dalla classe dell'oggetto stesso, ma è una pratica sconsigliata (tant'evvero che eclipse ti segnala un warning); Classi e oggetti hanno contesti diversi, sinceramente non trovo sbagliato che per accedere a un campo definito dalla classe una istanza debba passare esplicitamente dalla classe stessa (anche se lui stesso è una istanza di quella classe).
Se usassi sempre l'operatore '->' non saresti più in grado, leggendo il codice, di capire se stai accedendo a una variabile della classe o dell'oggetto e sinceramente io credo sia uno svantaggio.
Anche in altri linguaggi (C++, Delphi sicuramente) si può fare a meno dell'operatore di scope resolution per accedere agli attributi statici di una classe.

Personalmente io trovo che un oggetto debba poter accedere a un qualunque attributo, sia esso suo (di istanza) o della classe a cui appartiene, sempre allo stesso modo. Si tratta di un modello omogeneo e coerente: si tratta sempre di attribuiti definiti da una classe e che essa mette a disposizione delle sue istanze (o degli "eredi").
Per quanto riguarda il rifattorizzare direi che è un problema di strumento e molto più generale che questo caso specifico. Uno strumento fatto bene fa sì che in tutte le operazioni di refactoring tutte le reference siano aggiustate (come succede in java usando eclipse) o errori segnalati prima della fase di esecuzione.
Questo lo puoi fare con un linguaggio non dinamico, come Java (OK, con la reflection è un po' dinamico), ma con quelli dinamici come PHP, Python, Ruby, ecc. è abbastanza difficile perché il processo di rifattorizzazione non può certo essere automatizzato.
Insomma, secondo me questa tua osservazione è quanto meno opinabile e comunque sicuramente non valida in senso assoluto come ben altre evidenze che hai scritto.
Sicuramente: abbiamo idee diverse. :)
No dai, non puoi dire che "/* */" è concepito solo ed esclusivamente per racchiudere blocchi di codice. Non puoi tralasciare il fatto di dover scrivere commenti di più righe che non devono finire nel javadoc.
E di riflesso se uno volesse scrivere commenti su più righe potrebbe benissimo far partire ogni riga con //.
Ci sono diversi modi di scrivere commenti in php come in java...
in java hanno significati diversi solo per come vengono interpretati e in php potrebbe benissimo essere lo stesso.
Indubbiamente, ma // e /* */ sono nati comunque per scopi diversi. Il primo per inserire commenti di fine riga, i secondi per definire commenti che possono abbracciare più righe di codice.

Poi, ripeto, ci possono essere le eccezioni, non c'è problema. ;)
E vedrai che aumenteranno ancora!
Aspettiamo allora. :D
Solo basta che non sia per "opinioni"! ;-)
In quella pagina ci sono anche quelle proprio perché, come vedi, non ci può essere sempre uniformità di vedute.

Prendiamo Python: c'è gente a cui non piace assolutamente l'idea dell'indentazione usata per delimitare i blocchi; preferirebbero le {}, begin/end, ecc.
Quindi quella paginetta potrebbe benissimo essere aggiornata e aggiunta una riga: "Python sucks because: blocks aren't delimited by curly braces".

Nulla da dire: è un'opinione legittima e io non ho nulla da obiettare. :)

franksisca
15-08-2008, 12:03
ovviamente iscritto... :D

71104
15-08-2008, 13:36
+2 per C++ Sucks.

gugo, quand'è che ci scrivi 'sta sezione sul C#? :D

gugoXX
15-08-2008, 14:41
+2 per C++ Sucks.

gugo, quand'è che ci scrivi 'sta sezione sul C#? :D

Nel Weekend spero, o alla peggio la prossima settimana, quando dovrei essere un po' piu' scarico.
Non mi chiedere di fare la sezione SQL, senno' finisco lo spazio del server. :D

Hiskrtapps
18-08-2008, 18:21
Sì, esattamente. :)
In tal caso i tag potrebbero essere almeno opzionali. Normalmente un file include... viene incluso e basta, quindi perché portarsi dietro sempre e comunque i tag?

perchè altrimenti quando tu fai qualcosa stai già decidendo come deve essere usata, mettendo o no i tag. Ma quello che fai te potrebbero usarla più persone con scopo diverso, quindi per me è corretto che una volta deciso che php va sempre racchiuso tra tag, non ci siano eccezioni a questo.
Poi ripeto, siamo d'accordo entrambi che, come negli esempi che mi hai portato, se ne potesse fare a meno.


No, intendevo quelle definite con define, appunto. :D
Su "const"... scrivi pure, scrivi pure. :D

prossimamente.


Anche in altri linguaggi (C++, Delphi sicuramente) si può fare a meno dell'operatore di scope resolution per accedere agli attributi statici di una classe.
Personalmente io trovo che un oggetto debba poter accedere a un qualunque attributo, sia esso suo (di istanza) o della classe a cui appartiene, sempre allo stesso modo. Si tratta di un modello omogeneo e coerente: si tratta sempre di attribuiti definiti da una classe e che essa mette a disposizione delle sue istanze (o degli "eredi").

Non è solo questione di piacere o meno in questo caso.
Se accedessi allo stesso modo la proprietà di istanza nasconderebbe la proprietà di classe e questo potrebbe portare a dei problemi (java li ha e infatti la pratica viene deprecata).
O stiamo dicendo che vogliamo consentire a una proprietà pubblica di classe di essere nascosta da quella pubblica di istanza? O vogliamo che si impedisca a una proprietà pubblica di avere lo stesso nome di quella pubblica di classe (o anche protected)?
Php, tra le tante pecche, ti evita di incorrere in questi problemi (ne è proprio esente!! una volta che fa una cosa buona!).
Io resto dell'idea che sarebbe da segnalare il contrario.


Questo lo puoi fare con un linguaggio non dinamico, come Java (OK, con la reflection è un po' dinamico), ma con quelli dinamici come PHP, Python, Ruby, ecc. è abbastanza difficile perché il processo di rifattorizzazione non può certo essere automatizzato.

c'è tanta roba che si può automatizzare. Esistono ambienti per php (basati su eclipse) che gestiscono il refactoring in maniera sufficiente. Sicuramente si può fare di più.


Sicuramente: abbiamo idee diverse. :)

ma neanche poi tanto


Prendiamo Python: c'è gente a cui non piace assolutamente l'idea dell'indentazione usata per delimitare i blocchi; preferirebbero le {}, begin/end, ecc.
Quindi quella paginetta potrebbe benissimo essere aggiornata e aggiunta una riga: "Python sucks because: blocks aren't delimited by curly braces".

Nulla da dire: è un'opinione legittima e io non ho nulla da obiettare. :)

ma è solo per il piacere di parlarne!! ;-)

cdimauro
18-08-2008, 20:53
perchè altrimenti quando tu fai qualcosa stai già decidendo come deve essere usata, mettendo o no i tag. Ma quello che fai te potrebbero usarla più persone con scopo diverso, quindi per me è corretto che una volta deciso che php va sempre racchiuso tra tag, non ci siano eccezioni a questo.
Poi ripeto, siamo d'accordo entrambi che, come negli esempi che mi hai portato, se ne potesse fare a meno.
Ti faccio un esempio: Pascal e derivati. Il programma principale inizia e finisce così:
program NomeProgramma;
... (* Eventuali variabili, costanti, tipi e definizioni di procedure e funzioni. *)
begin
(* Codice del programma principale. *)
end.
E' possibile includere file con la direttiva $I, ma i file non devono essere racchiusi da nessun tag o istruzione.

Idem per il C: i file vengono inclusi così come sono.

Poi, va bene, hanno scelto così e... amen: non ci si può far nulla, ma come modello è veramente brutto.
Non è solo questione di piacere o meno in questo caso.
Se accedessi allo stesso modo la proprietà di istanza nasconderebbe la proprietà di classe e questo potrebbe portare a dei problemi (java li ha e infatti la pratica viene deprecata).
O stiamo dicendo che vogliamo consentire a una proprietà pubblica di classe di essere nascosta da quella pubblica di istanza? O vogliamo che si impedisca a una proprietà pubblica di avere lo stesso nome di quella pubblica di classe (o anche protected)?
Php, tra le tante pecche, ti evita di incorrere in questi problemi (ne è proprio esente!! una volta che fa una cosa buona!).
Io resto dell'idea che sarebbe da segnalare il contrario.
Un attributo d'istanza ne nasconde uno di classe se è definito in una sottoclasse, per cui si può sempre ricorrere all'istruzione super oppure tramite l'operatore di scoping per accedervi.

Sono casi speciali, come speciale è il fatto che una sottoclasse definisca un attributo d'istanza quando ne esiste già uno, che addirittura è di classe.

In questi casi c'è qualcosa di profondamente sbagliato, IMHO: non dovrebbe mai succedere (come mai dovrebbe succedere che una classe implementi due interfacce che hanno un metodo con lo stesso nome).

A mio avviso nella normalità c'è la coerenza di vedere e accedere a tutti gli attributi nello stesso modo.
c'è tanta roba che si può automatizzare. Esistono ambienti per php (basati su eclipse) che gestiscono il refactoring in maniera sufficiente. Sicuramente si può fare di più.
Lo vedo difficile, proprio per il fatto che stiamo parlando di linguaggi dinamici.

Non v'è dubbio che facendo del "guessing" si possa risalire a qualcosa, ma si tratta di un'operazione rischiosa poiché non certa: è sulla base di qualche supposizione.
ma neanche poi tanto
:)
ma è solo per il piacere di parlarne!! ;-)
Già. Quella paginetta su wiki non ha certo motivo d'essere un trattato scientifico. :D

dupa
18-08-2008, 21:24
Prendiamo Python: c'è gente a cui non piace assolutamente l'idea dell'indentazione usata per delimitare i blocchi; preferirebbero le {}, begin/end, ecc.
Quindi quella paginetta potrebbe benissimo essere aggiornata e aggiunta una riga: "Python sucks because: blocks aren't delimited by curly braces".

Nulla da dire: è un'opinione legittima e io non ho nulla da obiettare. :)

Non è un'opinione.
Usare l'indentazione per definire inizio / fine di blocchi di codice porta a commettere facilmente errori.
Quando hai messo le { e } dai un colpo di "Format" dal tuo IDE di fiducia e ti ritrovi tutto indentato.

cdimauro
18-08-2008, 22:11
Lo stesso vale per Python: il mio IDE di fiducia (SPE) mi segnala IMMEDIATAMENTE se il blocco è indentato male, e se provo a salvare si posiziona sempre sulla riga incriminata marcando in rosso l'indentazione errata. :O
Non commetto errori di indentazione con Python da quando utilizzo SPE, ossia da un po' di anni. :cool:

In compenso prova in C, C++, ecc. a dimenticare di inglobare le istruzioni dentro le parentesi graffe: specialmente in blocchi con if (peggio ancora le catene if/else) è facile che venga eseguita UNA sola istruzione anziché tutte quelle previste, coi risultati che puoi ben immaginare.
E dubito che il tuo IDE riesca a segnalartelo quest'errore: sintatticamente il sorgente è perfettamente valido. ;)

dupa
18-08-2008, 23:09
In compenso prova in C, C++, ecc. a dimenticare di inglobare le istruzioni dentro le parentesi graffe: specialmente in blocchi con if (peggio ancora le catene if/else) è facile che venga eseguita UNA sola istruzione anziché tutte quelle previste, coi risultati che puoi ben immaginare.
E dubito che il tuo IDE riesca a segnalartelo quest'errore: sintatticamente il sorgente è perfettamente valido. ;)

e infatti io uso SEMPRE le graffe anche se ho solo un'istruzione
MAI FIDARSI DELL'INDENTAZIONE!
e infatti non potrei mai usare un linguaggio basato sull'indentazione, la graffe non tradiscono mai.

cdimauro
18-08-2008, 23:21
Nemmeno l'indentazione: basta usare un buon IDE, come dicevi prima tu. :read:

nico159
19-08-2008, 00:57
e infatti io uso SEMPRE le graffe anche se ho solo un'istruzione
MAI FIDARSI DELL'INDENTAZIONE!
e infatti non potrei mai usare un linguaggio basato sull'indentazione, la graffe non tradiscono mai.
if (x) {
Oppure?
if (x)
{
Senza contare
if (x) {
---------------;
---------------;
---------------;
---------------;
---------------;
---------------;
}

Oppure ancora
if (x)
if (y)
-------;
else
-------;
Con quale if va else?

cdimauro
19-08-2008, 08:22
La terza è veramente molto bella: mi piacciono gli alberi di natale... :asd:

recoil
19-08-2008, 11:52
Secondo me manca una sezione "C# sucks because" in quel wiki. :fiufiu: :D


beh c'è anche il goto che erroneamente era stato attribuito a Java
in C# c'è veramente, è una buona scusa per aggiungerlo :D

quella sul Visual Basic di RaouL_BennetH è semplicemente da :ave: :asd:

dupa: anche io metto sempre le graffe il 99% delle volte anche in caso di una sola istruzione, trovo aiuti la leggibilità e mi permette di evitare vaccate :)

cdimauro
19-08-2008, 13:40
Ma Raoul sul Visual Basic che ha scritto? Nel wiki non c'è nulla. :stordita:

71104
19-08-2008, 14:24
in C# c'è veramente, è una buona scusa per aggiungerlo :D aggiudicato, inserisco una nuova sezione sul C# con la scusa del goto per incitare gugoXX a metterci altre cose :D

gugoXX
19-08-2008, 15:07
aggiudicato, inserisco una nuova sezione sul C# con la scusa del goto per incitare gugoXX a metterci altre cose :D

:D
Ci sono ci sono, prima di andare in ferie scrivo qualcosa, promesso.
Pero' per par condicio anche cdimauro dovrebbe mettere qualcosa sul Python... Io mi sto sforzando almeno, e 2 cose, anche se molto specifiche, le ho trovate.

cdimauro
19-08-2008, 15:09
:D
Ci sono ci sono, prima di andare in ferie scrivo qualcosa, promesso.
Pero' per par condicio anche cdimauro dovrebbe mettere qualcosa sul Python... Io mi sto sforzando almeno, e 2 cose, anche se molto specifiche, le ho trovate.
No, dai, non puoi chiedermi questo. :sob:

M'ero messo ad arricchire la pagine di Ruby: va bene lo stesso, no? :fagiano:

banryu79
19-08-2008, 15:25
No, dai, non puoi chiedermi questo. :sob:

M'ero messo ad arricchire la pagine di Ruby: va bene lo stesso, no? :fagiano:

No, vogliamo assolutamente le tue critiche al Serpente :D
Siamo smaniosi di apprende dal profeta, su su, illuminaci anche sulle pecche, non vorrai che si pensi che i tuoi giudizi su Python sian troppo parziali :Prrr: :D

71104
19-08-2008, 16:03
:rotfl:

71104
19-08-2008, 16:25
altri 2 per il C++. come ho fatto a dimenticarmi che il C++ non supporta il multithreading!!

gugoXX
19-08-2008, 17:12
Ne ho un'altra per il C#.
La keyword using.

La keyword using in realta' sono 2 keywords, con 2 significati assolutamente differenti.
Il primo uso e' simile alla include del C

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


Il secondo e' invece per dichiarare lo scope di un ben specifico oggetto appena creato.
Al termine dello scope l'oggetto verra' distrutto, ma verra' anche invocato direttamente il GarbageCollector, per concluedere immediatamente il ciclo di esistenza.
La using assicura che l'oggetto verra' distrutto (Disposed) anche se in mezzo alla using c'e' un'istruzione di flusso, come la return di questo esempio.

using (DBContext db=DBContextFactory.CreateDatabase("connessione"))
{
int par = db.query1();
return par;
}




Ora, fatto salvo che il compilatore sa bene dove si trova e cosa sta facendo in quel momento.
Ma era proprio necessario usare la stessa parola con 2 significati completamente diversi?
Carenza di fantasia?

DanieleC88
19-08-2008, 19:59
Carenza di fantasia?
Probabile. :D

Mi pare di ricordare che in Visual Basic ci fosse qualcosa di lontanamente simile (anche se con un significato diverso):
With <Oggetto>
.Proprietà = Valore
.Metodo()
End With

Magari potevano riciclare la keyword per questo scopo e togliere l'ambiguità... :)

dupa
19-08-2008, 20:35
Con quale if va else?

basta che dai dal tuo editor di fiducia un colpo di format e ti ritrovi tutto leggibilissimo.
nel momento in cui sbagli l'indentazione con python sei fregato.

^TiGeRShArK^
19-08-2008, 20:40
Mi domando chi è stato il maledetto alla Microsoft ad inventare shortcut da tastiera del tipo CTRL + K, CTRL + D (per formattare se non ricordo male), mentre in eclipse e in ogni altro editor per una cosa comune come la formattazione si usa CTRL + SHIFT + F o ALT + SHIFT + F in netbeans se non ricordo male... :muro:

cdimauro
19-08-2008, 20:59
No, vogliamo assolutamente le tue critiche al Serpente :D
Siamo smaniosi di apprende dal profeta, su su, illuminaci anche sulle pecche, non vorrai che si pensi che i tuoi giudizi su Python sian troppo parziali :Prrr: :D
Il problema è che per me è molto difficile trovare qualche difetto: Python mi ha obnubilato la mente ormai (e non scherzo!). :stordita:
Ne ho un'altra per il C#.
La keyword using.

La keyword using in realta' sono 2 keywords, con 2 significati assolutamente differenti.
Il primo uso e' simile alla include del C

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


Il secondo e' invece per dichiarare lo scope di un ben specifico oggetto appena creato.
Al termine dello scope l'oggetto verra' distrutto, ma verra' anche invocato direttamente il GarbageCollector, per concluedere immediatamente il ciclo di esistenza.
La using assicura che l'oggetto verra' distrutto (Disposed) anche se in mezzo alla using c'e' un'istruzione di flusso, come la return di questo esempio.

using (DBContext db=DBContextFactory.CreateDatabase("connessione"))
{
int par = db.query1();
return par;
}

Ora, fatto salvo che il compilatore sa bene dove si trova e cosa sta facendo in quel momento.
Ma era proprio necessario usare la stessa parola con 2 significati completamente diversi?
Carenza di fantasia?
Hanno voluto risparmiare sulle keyword, perché la scelta è stata pessima.
Probabile. :D

Mi pare di ricordare che in Visual Basic ci fosse qualcosa di lontanamente simile (anche se con un significato diverso):
With <Oggetto>
.Proprietà = Valore
.Metodo()
End With
No, questo è preso a piene mani dal with di Pascal & co.

Quello usato in C# invece è molto simile al with di Python, che serve a garantire la "finalizzazione" della risorsa allocata.
Magari potevano riciclare la keyword per questo scopo e togliere l'ambiguità... :)
Potevano metter with come Python. :cool:
basta che dai dal tuo editor di fiducia un colpo di format e ti ritrovi tutto leggibilissimo.
nel momento in cui sbagli l'indentazione con python sei fregato.
Come ti ho già detto ma vedo che non vuoi capire, ma soprattutto come dicevi TU prima, se hai un IDE decente questi problemi non li hai. E infatti errori di indentazione non ne commetto da EONI, grazie a SPE.

Idem per gli errori dovuti a errori di digitazione delle variabili: mi basta un colpetto di PyChecker e il sorgente viene analizzato da cima a fondo riportando eventuali errori commessi (o codice inutile).
Mi domando chi è stato il maledetto alla Microsoft ad inventare shortcut da tastiera del tipo CTRL + K, CTRL + D (per formattare se non ricordo male), mentre in eclipse e in ogni altro editor per una cosa comune come la formattazione si usa CTRL + SHIFT + F o ALT + SHIFT + F in netbeans se non ricordo male... :muro:
Mumble. Con SPE per indentare e deindentare utilizzo TAB e Shift + Tab, e mi trovo bene.

^TiGeRShArK^
19-08-2008, 21:04
Mumble. Con SPE per indentare e deindentare utilizzo TAB e Shift + Tab, e mi trovo bene.
Per indentare e deindentare pure io....infatti parlavo della formattazione del sorgente :asd:

71104
19-08-2008, 21:04
Mi domando chi è stato il maledetto alla Microsoft ad inventare shortcut da tastiera del tipo CTRL + K, CTRL + D (per formattare se non ricordo male), mentre in eclipse e in ogni altro editor per una cosa comune come la formattazione si usa CTRL + SHIFT + F o ALT + SHIFT + F in netbeans se non ricordo male... :muro: OT

^TiGeRShArK^
19-08-2008, 21:05
OT

mmmm....
Si potrebbe creare il sito YourEditorSucks :O

:asd:

cdimauro
19-08-2008, 21:31
vi sarebbe al primo posto, seguito a ruota da emacs. :asd:

DanieleC88
19-08-2008, 22:11
No, questo è preso a piene mani dal with di Pascal & co.
Sono talmente tanti anni che non li uso che comincio a confondere Visual Basic e Pascal. Come sono finito male. :D
Quello usato in C# invece è molto simile al with di Python, che serve a garantire la "finalizzazione" della risorsa allocata.

Potevano metter with come Python. :cool:
Vabbe' era quello che intendevo dire anche io, solo che ho fatto un'insalata coi linguaggi. :p
vi sarebbe al primo posto, seguito a ruota da emacs. :asd:
Sbagliato: EMACS rientra nella categoria dei sistemi operativi. :asd:
Io invece con VIM mi ci trovo benissimo. :O (se dici il vi "classico", nudo e crudo, quello è più scomodo in effetti)

marco.r
19-08-2008, 22:13
vi sarebbe al primo posto, seguito a ruota da emacs. :asd:

E sarebbero gli unici editor presenti, perche' sono i soli degni di tal nome :O :p

marco.r
19-08-2008, 22:19
Mi domando chi è stato il maledetto alla Microsoft ad inventare shortcut da tastiera del tipo CTRL + K, CTRL + D (per formattare se non ricordo male), mentre in eclipse e in ogni altro editor per una cosa comune come la formattazione si usa CTRL + SHIFT + F o ALT + SHIFT + F in netbeans se non ricordo male... :muro:

Eresia !
ctrl+d = cancella carattere corrente
ctrl+k = cancella fino a fine riga (o la riga stessa, se e' vuota).
:O

cdimauro
19-08-2008, 22:23
Sono talmente tanti anni che non li uso che comincio a confondere Visual Basic e Pascal. Come sono finito male. :D
Ma qui mica li hai confusi: per quella funzionalità fanno esattamente lo stesso lavoro. :p
Sbagliato: EMACS rientra nella categoria dei sistemi operativi. :asd:
EMACS è quell'oggetto che se ti viene in mente di fargli fare una cosa, sicuramente qualcuno (Stallman :asd:) c'ha già pensato e gliel'ha infilata. :D
Io invece con VIM mi ci trovo benissimo. :O (se dici il vi "classico", nudo e crudo, quello è più scomodo in effetti)
Anche VIM. Niente, non ce la faccio a digerirli.
E sarebbero gli unici editor presenti, perche' sono i soli degni di tal nome :O :p
Io in tutte le macchine di produzione ho fatto mettere joe: l'unico editor per esseri umani.

P.S. D'altra parte cosa ci si può aspettare da un s.o. che è pieno di -h. :asd:

DanieleC88
19-08-2008, 22:31
Ma qui mica li hai confusi: per quella funzionalità fanno esattamente lo stesso lavoro. :p
Ancora peggio, significa che non me li ricordo! (il che credo sia anche un bene, per quanto riguarda Visual Basic :asd: )

^TiGeRShArK^
20-08-2008, 01:01
Eresia !
ctrl+d = cancella carattere corrente
ctrl+k = cancella fino a fine riga (o la riga stessa, se e' vuota).
:O

In Visual Studio? :mbe:
..vabbè che non lo apro da due settimane..
ma leggendo qui (http://www.codinghorror.com/blog/files/Visual%20Studio%20.NET%202005%20Keyboard%20Shortcuts.htm) mi sa che non ho detto una cazzata :asd:

^TiGeRShArK^
20-08-2008, 01:03
Anche VIM. Niente, non ce la faccio a digerirli.

QUOTISSIMO :O

:asd:

marco.r
20-08-2008, 01:08
In Visual Studio? :mbe:
..vabbè che non lo apro da due settimane..
ma leggendo qui (http://www.codinghorror.com/blog/files/Visual%20Studio%20.NET%202005%20Keyboard%20Shortcuts.htm) mi sa che non ho detto una cazzata :asd:
Mi sono spiegato male. Intendevo dire che un vero editor usa le combinazioni che ho riportato sopra, non mi riferivo a VS in particolare :p

^TiGeRShArK^
20-08-2008, 01:15
Mi sono spiegato male. Intendevo dire che un vero editor usa le combinazioni che ho riportato sopra, non mi riferivo a VS in particolare :p

ah ecco :p

boh..
Eclipse con CTRL + D cancella la riga, la cancellazione fino al carattere corrente non l'ho mai usata e non so come si faccia :p
però il fatto di poter spostare le righe di codice selezionate a piacimento e di poterle duplicare utilizzando ALT o CTRL + le freccette su e giù è davvero uno spettacolo....che ovviamente in Visual Studio manca :asd:

71104
20-08-2008, 18:19
oggi mi sentivo particolarmente in vena e ne ho aggiunti altri due su Java :P


Every, single, object, has its own synchronization mechanism, even those that you never synchronize on, resulting in unnecessary resource consumption. If you declare the dummiest Vector<Integer>, each element of your vector will have a synchronization monitor; and of course you will never synchronize on them.
Many standard classes do parameter checking and throw unchecked exceptions such as NullPointerException and IllegalArgumentException. No problem; but what are the assertions for, then?


che ne pensate?

cdimauro
20-08-2008, 20:49
A me me piace. :D

banryu79
21-08-2008, 09:21
che ne pensate?
Every, single, object, has its own synchronization mechanism, even those that you never synchronize on, resulting in unnecessary resource consumption. If you declare the dummiest Vector<Integer>, each element of your vector will have a synchronization monitor; and of course you will never synchronize on them.

Non capisco, il fatto che Vector sia synchronized è risaputo; ma se non serve la sincronizzazione sulla collezione allora si usa ArrayList, per esempio.
Probabilmente sono io che non ho capito l'obiezione, in tal caso perdonatemi l'ignoranza: quali sono le "resource consumption" dovute al fatto che ogni singolo oggetto ha il suo meccanismo di sincronizzazione? Ammetto di non saperlo.

71104
21-08-2008, 13:02
Non capisco, il fatto che Vector sia synchronized è risaputo; ma se non serve la sincronizzazione sulla collezione allora si usa ArrayList, per esempio.
Probabilmente sono io che non ho capito l'obiezione, in tal caso perdonatemi l'ignoranza: quali sono le "resource consumption" dovute al fatto che ogni singolo oggetto ha il suo meccanismo di sincronizzazione? Ammetto di non saperlo. non parlo della particolare implementazione sincronizzata della classe Vector, ma del fatto che ogni singolo oggetto Java è dotato di un monitor di sincronizzazione; anche ArrayList ha il suo, e ce l'hanno pure tutti gli oggetti Integer contenuti nel tuo Vector<Integer> o nella tua ArrayList<Integer>. hai presente lo statement synchronized?

in effetti è anche colpa mia, devo spiegarlo meglio nella pagina.

banryu79
21-08-2008, 13:27
non parlo della particolare implementazione sincronizzata della classe Vector, ma del fatto che ogni singolo oggetto Java è dotato di un monitor di sincronizzazione; anche ArrayList ha il suo, e ce l'hanno pure tutti gli oggetti Integer contenuti nel tuo Vector<Integer> o nella tua ArrayList<Integer>. hai presente lo statement synchronized?

Ok, ma "cosa/quanto" sarebbe questo costo in termini di risorse, che ogni oggetto porta con se (cioè quanto costa il fatto di avere un monitor)?
Altra domanda: non è che questo aspetto è strettamente neccesario per implementare il multithreading in Java?

Se sì allora per par condicio bisognerebbe aggiungere a tutti gli altri linguaggi che non supportano il multithreading "it sucks because it doesn't support multithreading natively", :rolleyes:

71104
21-08-2008, 15:01
Ok, ma "cosa/quanto" sarebbe questo costo in termini di risorse, che ogni oggetto porta con se (cioè quanto costa il fatto di avere un monitor)? che sia tanto o poco non dipende dalle specifiche di Java, o almeno non credo (in realtà bisognerebbe verificare leggendo anche le specifiche della virtual machine); ma il solo fatto che per definizione ogni singolo programma Java debba avere un overhead e non possa controllarlo è un sucks.

e poi quando conti tutti ma proprio tutti gli oggetti che viaggiano in un'istanza di un programma Java (comprese le stringhe, e intendo anche i literals), fosse anche un solo byte a oggetto va a finire che per un programma molto grosso e che istanzia parecchio hai sprecato un megabyte se non di più. si ok, siamo nel 2008 ed è un problema insignificante, però è un sucks; oh. :O


Altra domanda: non è che questo aspetto è strettamente neccesario per implementare il multithreading in Java? certo che lo è, perché Java è stato progettato così; avrebbe potuto essere progettato in un'altra maniera. come dire, non è che il fatto che il C++ non supporti il networking è necessario affinché il linguaggio sia portabile anche su piattaforme molto limitate? certo che lo è, però se permetti nel 2008 è un sucks.

71104
21-08-2008, 15:02
Se sì allora per par condicio bisognerebbe aggiungere a tutti gli altri linguaggi che non supportano il multithreading "it sucks because it doesn't support multithreading natively", :rolleyes: infatti ce l'ho messo nel C++

ndakota
21-08-2008, 15:10
forse l'unico vero problema è che state appunto sucksando(passatemi il verbo :O ) solo i linguaggi che conoscete maggiormente e a leggere quella pagina sembra che si debba stare lontani da C++/Java quando invece sono le scelte più popolari(o quasi).

cdimauro
21-08-2008, 15:24
Guarda che sbagli: leggendo quella pagina si evince che bisogna star lontanissimi da PHP. :asd:

banryu79
21-08-2008, 15:39
*snip*

Thanks per le spiegazioni, l'unica cosa che non mi torna è il circolo vizioso dato dal fatto che:

- se supporta il multithreading un linguaggio non lo fa "aggratisse" e quindi sucks
- se non supporta il multithreading, bhe, sucks

della serie: nessuno si salva, sempre si becca un sucks in ogni caso :asd: :sofico:

Matrixbob
21-08-2008, 15:46
... e ABL di Progress non suca? L:DL

cdimauro
21-08-2008, 15:48
Thanks per le spiegazioni, l'unica cosa che non mi torna è il circolo vizioso dato dal fatto che:

- se supporta il multithreading un linguaggio non lo fa "aggratisse" e quindi sucks
- se non supporta il multithreading, bhe, sucks

della serie: nessuno si salva, sempre si becca un sucks in ogni caso :asd: :sofico:
Si può sempre supportare il multithreading senza allocare risorse in più per qualunque cosa. :fiufiu:

banryu79
21-08-2008, 15:51
Si può sempre supportare il multithreading senza allocare risorse in più per qualunque cosa. :fiufiu:
...
Python? :D

cdimauro
21-08-2008, 15:55
:fiufiu: :fiufiu: :fiufiu:

marco.r
21-08-2008, 16:00
...
Python? :D

Il multithreading di python meriterebbe un angolino tutto suo in quella pagina... :p

cdimauro
21-08-2008, 16:13
Aggiornala pure. :)

71104
21-08-2008, 17:17
Si può sempre supportare il multithreading senza allocare risorse in più per qualunque cosa. :fiufiu: esattamenteh :O

banryu79
21-08-2008, 17:55
Il multithreading di python meriterebbe un angolino tutto suo in quella pagina... :p

Aggiornala pure. :)

cdimauro, te proprio non ne vuoi sapere di scrivere qualche sucks sul Pitone, eh!
Eppure conoscendolo così bene saresti il candidato migliore :read:

cdimauro
21-08-2008, 19:52
cdimauro, te proprio non ne vuoi sapere di scrivere qualche sucks sul Pitone, eh!
Eppure conoscendolo così bene saresti il candidato migliore :read:
C'è qualche punto che ho in mente di scrivere, ma sul multithreading onestamente c'ho lavorato poco e finora di "magagne" non ne ho trovate.

Sono sicuro che Marco, per parlare così, vuol dire che ne ha trovare, e a parte scriverlo nella paginetta (che ci sta sicuramente: è fatta apposta :D), a me interessa comprendere quali siano i loro limiti / problemi.

Comunque al momento mi sto studiando la virtual machine di CPython (è una vera tortura, visto che... è scritta in C :cry:) per cui ho poco tempo per dedicarmi ad altro. Vediamo se nel fine settimana qualche voce la posso aggiungere. ;)

nico159
22-08-2008, 01:09
http://c2.com/cgi/wiki?PythonProblems
Qualcuno va di commentare? (anche se molti punti sono ridicoli) :ciapet:

cdimauro
22-08-2008, 08:19
Concordo. Comunque qualche spunto c'è. Appena ho un po' di tempo me lo leggo per bene e aggiorna "Python sucks". :)

WarDuck
22-08-2008, 09:48
non parlo della particolare implementazione sincronizzata della classe Vector, ma del fatto che ogni singolo oggetto Java è dotato di un monitor di sincronizzazione; anche ArrayList ha il suo, e ce l'hanno pure tutti gli oggetti Integer contenuti nel tuo Vector<Integer> o nella tua ArrayList<Integer>. hai presente lo statement synchronized?

in effetti è anche colpa mia, devo spiegarlo meglio nella pagina.

Non ho capito bene cosa intendi dire, senza la parola chiave synchronized il metodo o il particolare statment non è sincronizzato.

Cioè se tu accedi a quella variabile mentre in uso da un altro thread ti viene lanciata l'eccezione. Se tutte le variabili fossero sincronizzate non ci sarebbe bisogno di mettere synchronized o gestire monitor e lock manualmente (e lo so bene dato che c'ho fatto un esame il 28 luglio :sofico: ) .

Se proprio dobbiamo mettere dei punti deboli nel meccanismo, allora direi che sarebbe meglio non usare proprio il monitor con il lock di default, ma usare un ReentrantLock col costrutto try-finally.

Poi non so, magari ho capito male io.

banryu79
22-08-2008, 09:55
Ciao WarDuck,
credo che il problema sia dovuto al fatto che la classe Object, radice di tutta la gerarchia di classi in Java, implementa questi metodi:
- notify(); notifyAll(); e i tre wait().

Questo implica che un oggetto Object abbia un monitor, quindi che tutte le classi che eraditano da Object abbiano un monitor.
Il fatto è che non ho la più pallida idea di cosa sia *esattamente* questo monitor in termini di risorse; per questo chiedevo maggiori delucidazioni.

cdimauro
22-08-2008, 10:03
Nemmeno io conosco questi dettagli, ma è una cosa che concettualmente non mi piace.

Per essere precisi, non è che l'accesso a TUTTE le variabili sia "a rischio" quando si lavora coi thread. Al contrario: in genere sono poche e precise variabili che hanno bisogno di un "monitoraggio" / "accesso regolato".

In questo caso sono io, programmatore, a piazzare gli opportuni lock nelle parti di codice che fanno accesso ad esse (le famigerate "sezioni critiche" spiegate alle lezioni di "Sistemi Operativi" :D).

WarDuck
22-08-2008, 10:23
Si avete ragione, a quanto pare ogni oggetto ha appunto il suo lock di default...

Every object has an intrinsic lock associated with it.

In effetti per usare il synchronized su un oggetto è necessario che sia così. Però non so se questo Lock venga creato (o istanziato che dir si voglia) solo quando si usa appunto synchronized.

banryu79
22-08-2008, 10:29
Pensavo di ricevere maggiori lumi dando un'occhiata al sorgente java della classe Object (http://www.docjar.com/html/api/java/lang/Object.java.html): ma ovviamente sia la costruzione di un Object che le chiamate ai metodi sopraelencati sono invocazioni di metodi native che quindi non sono implementati nella definizione della classe ma vanno a chiamare codice nativo (e non ho tempo adesso di andare a frugare nelle dll del JDK...)

gugoXX
22-08-2008, 11:05
Magari alla fine sono metodi comuni per l'oggetto radice di tutti gli oggetti, quindi ipotizzo il cui codice sia presente una sola volta, senza ulteriore consumo di risorse/memoria.

es: In C# c'e' nativamente la keyword
lock
che permette di gestire regioni critiche semplici.

un possibile utilizzo e'

...
lock(pippo)
{
valore=valore+2;
}
...

In questo modo sono sicuro che valre viene incrementato di 2 in regione critica, in quanto un solo processo per volta puo' richiedere il controllo di pippo.

Magari in Java la stessa cosa e' stata fatta con una funzione presente per tutti gli oggetti, e quindi ereditata su qualsiasi oggetto, vecchio o nuovo.

...
pippo.AcquireLock();
valore=valore+2;
pippo.ReleaseLock();
...


In un linguaggio fortemente object oriented sarebbe stato un errore, forse neppure possibile, permettere una funzione globale al di fuori di qualsiasi classe (stile funzione globale C o C++)

In Java hanno (forse) scelto la via del metodo comune a tutti.
In C# quello di una keyword.
A parte la differenza di sintassi mi sembrerebbero equivalenti, in quanto relativamente alle classi il codice viene istanziato una volta sola. Quello che cambia e che e' allocato piu' volte sono i dati.

WarDuck
22-08-2008, 12:11
Quello che dici te si può fare col synchronized.

synchronized(Object o) {
...
}

Si può fare anche con i metodi interi (perdonatemi se questa sintassi non è corretta):

public void synchronized test() {
...
}

In questo caso però il lock viene rilasciato solo quando il metodo ritorna, quindi occorre verificare se si può adattare al contesto che ci serve.

Altrimenti tramite un lock esplicito:

public void test() {
ReentrantLock lock = new ReentrantLock();
lock.lock();
try {
...
}
finally {
lock.unlock();
}

71104
24-08-2008, 15:08
up :O


per quanto riguarda l'uso dei lock espliciti, vorrei far notare che la loro implementazione usa CPU; o meglio, ricordo che l'implementazione di ReentrantReadWriteLock fa attese attive (cicli a vuoto) e spreca CPU, e questo a causa del fatto che non è possibile realizzare in Java un'implementazione che addormenti un thread in attesa; sarebbe possibile solo con JNI e chiamate di sistema (forse).

magix2003
24-08-2008, 16:18
Io per Java aggiungerei che permette di dichiarare le instance variable come pubbliche!

Che ne pensate?

71104
24-08-2008, 16:21
Io per Java aggiungerei che permette di dichiarare le instance variable come pubbliche!

Che ne pensate? deve essere chiaro quale sia il problema all'atto pratico; puoi fare un esempio di situazione problematica?
lo so che l'ingegneria del software vieta nel modo più categorico l'esposizione pubblica delle variabili membro, ma non ho mai capito il perché :D
dicono la "virtualizzazione", l' "astrazione dall'implementazione"... mah, io dico, uno mica è scemo :D se ha bisogno di astrarre lo sa

magix2003
24-08-2008, 16:29
Essendo Java un linguaggio orientato agli oggetti andare contro un suo principio fondamentale è già di per se un errore grave.

Esempio di problema:



public class SonoUnaClasseDemente {

public Oggetto unOggetto;

public void setOggetto(Oggetto unOggetto) {
this.unOggetto = unOggetto;
sideEffect();
}



Addesso supponiamo che il client non usi il setter :



SonoUnaClasseDemente unaDemente = new SonoUnaClasseDemente();
unaDemente.unOggetto = null;



Bene, in questo caso il side effect non verrà mai fatto!

71104
24-08-2008, 16:32
a me sembra più un errore di programmazione che un problema di Java... l'autore della classe poteva anche usare private per dichiarare quel membro, perché mai ha usato public? lo sapeva che in quel modo esisteva la possibilità del bug.

WarDuck
24-08-2008, 16:32
Per questo in C# c'è il getter e il setter :D

71104
24-08-2008, 16:34
piuttosto invece un sucks che mi viene in mente per Java è il mancato supporto di getters e setters (quello che trovi invece in C#).

magix2003
24-08-2008, 16:34
E' certamente un errore del programmatore, ma perché dare la possibilità che questo possa avvenire?

Sotto l'ottica del paradigma ad oggetti è incomprensibile. Infatti, in linguaggi "puri" come SmallTalk le variabili di istanza sono per forza protected.

71104
24-08-2008, 16:35
Per questo in C# c'è il getter e il setter :D bingo :p

71104
24-08-2008, 16:35
E' certamente un errore del programmatore, ma perché dare la possibilità che questo possa avvenire?

Sotto l'ottica del paradigma ad oggetti è incomprensibile. Infatti, in linguaggi "puri" come SmallTalk le variabili di istanza sono per forza protected. peggio me sento! :eek:
così sono visibili nelle sottoclassi :D

EDIT - per quanto riguarda il "dare la possibilità che ciò avvenga", io dico che in certi casi non fa alcun male dichiarare un membro come pubblico: se il getter e il setter sarebbero stati "puri" (cioè gettano/settano e non fanno nient'altro) non vedo il problema.

magix2003
24-08-2008, 16:42
peggio me sento! :eek:
così sono visibili nelle sottoclassi :D

EDIT - per quanto riguarda il "dare la possibilità che ciò avvenga", io dico che in certi casi non fa alcun male dichiarare un membro come pubblico: se il getter e il setter sarebbero stati "puri" (cioè gettano/settano e non fanno nient'altro) non vedo il problema.

Magari è più comodo, e tutti lo abbiamo fatto almeno una volta; ciò non toglie che sia una brutta forma di programmazione.

71104
24-08-2008, 16:48
[...] ciò non toglie che sia una brutta forma di programmazione. ok, e posso anche intuire il perché; ma siccome a quel wiki ci tengo :D allora vorrei che fosse il più possibile oggettivo e che non ci fosse nessunissima questione di gusti; "ciò non toglie che sia una brutta forma di programmazione" è un'espressione di gusti, a me invece piacerebbe capire che problema c'è nel dichiarare pubblica una variabile membro non statica che altrimenti sarebbe stata privata e avrebbe avuto un getter e un setter "puri" (passami il termine). perché altrimenti io potrei semplicemente rispondere: "brutta? e chi l'ha detto? a me le variabili pacciono pubbliche".

cdimauro
24-08-2008, 19:42
In Python non esiste il concetto di privato e protected: è tutto pubblico. :O

DanieleC88
24-08-2008, 19:55
In Python non esiste il concetto di privato e protected: è tutto pubblico. :O
Vero: le variabili istanziate in un oggetto le puoi anche eliminare se non ti servono! :D

magix2003
24-08-2008, 20:10
Python non lo conosco. Comunque io rimango della mia opinione, anche se magari in alcuni casi è prettamente una scelta di stile.

cdimauro
24-08-2008, 21:43
Vero: le variabili istanziate in un oggetto le puoi anche eliminare se non ti servono! :D
E anche aggiungerle, quando servono. :cool:

mik93
09-09-2008, 12:35
scusate se riporto un po' in su questo linguaggio ...... però mi è stato molto utile, dopo aver letto questo topic, penso di non imparare più il php, e sarei indeciso tra python (in caso aspetto la versione 3), java, c#, flash (action script 3)

mi piacerebbe creare sia applicazioni (programmi multipiattaforma) sia applicazioni web, di vario genere quale/i tra questi mi consigliate?? grazie mille

DanieleC88
09-09-2008, 13:31
dopo aver letto questo topic, penso di non imparare più il php, e sarei indeciso tra python
cdimauro miete vittime :asd:
mi piacerebbe creare sia applicazioni (programmi multipiattaforma) sia applicazioni web, di vario genere quale/i tra questi mi consigliate?? grazie mille
Be', che ti permetta di programmare facilmente e in modo che i programmi siano cross-platform, che si adatti tanto alla programmazione di applicazioni comuni che di applicazioni web... tra quelli citati, direi proprio Python. :D

Poi magari aspetta anche i consigli di altri.
ciao ;)

cdimauro
09-09-2008, 14:14
Direi che non c'è altro da dire. :p

mik93
10-09-2008, 13:27
okok quindi penso di aspettare la versione n° 3 di python (che adesso siamo alla beta) e intanto farmi una bella ripassata di html e css (che non fa mai male) e di imparare quacosina di flash/action script

una piccola domanda ci sono hosting free che supportono il python?

cdimauro
10-09-2008, 14:06
Non ne conosco, ma se ne trovi qualcuno, fammi sapere!!! :)

Quanto a Python, ti consiglio di cominciare già adesso.

Il 1 ottobre dovrebbe essere rilasciata la 2.6 finale, ma per la 3.0 in questi giorni nella mailling-list degli sviluppatori si parla di un rilasciato posticipato di un po'.

Tommo
10-09-2008, 21:02
In Python non esiste il concetto di privato e protected: è tutto pubblico. :O

E questo da quando è che è un bene? :asd:

mik93
10-09-2008, 22:22
quindi con python anche se volessi non potrei fare programmi a pagamento?? (non che lo farei però.... )

sei sicuro che mi conviene incominciare gia da adesso? io sono lentuccio .... per te (oracola butta a caso) fra quanto potrebbe uscire? si ragiona in mesi? 5? 10?

DanieleC88
10-09-2008, 23:21
quindi con python anche se volessi non potrei fare programmi a pagamento?? (non che lo farei però.... )
LOL, no, con "tutto è pubblico" cdimauro faceva riferimento alla visibilità degli oggetti e delle variabili tra le diverse parti del codice sorgente. :D
Puoi fare anche software commerciale volendo.
sei sicuro che mi conviene incominciare gia da adesso? io sono lentuccio .... per te (oracola butta a caso) fra quanto potrebbe uscire? si ragiona in mesi? 5? 10?

Difficile fare una stima, tutto dipende da cosa vuoi fare e da come vuoi farlo... Con impegno e costanza nel giro di qualche mese puoi avere i primi risultati incoraggianti, se le tue pretese non sono troppo esagerate. :D

cdimauro
11-09-2008, 08:26
E questo da quando è che è un bene? :asd:
Da quando si può estendere una classe anche se l'architetto coglionazzo di turno ha dichiarato "private" alcune cose che, invece, farebbe comodo poter cambiare (non sono rare le volte che m'è capitato; e mi son dovuto attaccare al tram: unica soluzione riscrivermi tutta la classe :muro:).

Poi non parliamo di protected, che è una burla: basta usare un cracker per aggirare tranquillamente questa limitazione (e per fortuna, direi: almeno qui ho la possibità di cambiare le cose).

Poi in un linguaggio dinamico in cui posso togliere e mettere "pezzi" (metodi, variabili) come e quando voglio è a dir poco paradossale il fatto che debba essere limitato dalle regole di visibilità.

In Python esiste un apposito name mangling per quanto riguarda l'importazione degli oggetti da un modulo e la dichiarazione di metodi, ma non c'è nessuna limitazione: un oggetto in ogni caso lo si può importare, se lo riteniamo opportuno / utile. ;)

x mik93: se sei "lentuccio", a maggior ragione è meglio cominciare subito. ;)

Hiskrtapps
11-09-2008, 09:27
Da quando si può estendere una classe anche se l'architetto coglionazzo di turno ha dichiarato "private" alcune cose che, invece, farebbe comodo poter cambiare (non sono rare le volte che m'è capitato; e mi son dovuto attaccare al tram: unica soluzione riscrivermi tutta la classe :muro:).

Se la classe è fatta bene e una variabile è privata vuole dire che ha senso che sia privata.
Se una cosa è privata e invece avrebbe dovuto essere public o protected è un problema del programmatore non del linguaggio.

cdimauro
11-09-2008, 09:59
Vero, ed è questo il problema: se mi trovo davanti a un programmatore che non ha saputo usare bene le regole di visibilità permesse dal linguaggio... m'attacco. Non posso fare NULLA.

Hiskrtapps
11-09-2008, 10:39
si ma la risposta non può essere fare tutto pubblico.
ma imparare a progettare la classe correttamente.

cdimauro
11-09-2008, 10:49
Preferisco avere un meccanismo di base che ti nasconde di default alcuni dettagli, ma permette comunque di accedervi, se lo ritieni necessario. ;)

Hiskrtapps
11-09-2008, 11:02
Preferisco avere un meccanismo di base che ti nasconde di default alcuni dettagli, ma permette comunque di accedervi, se lo ritieni necessario. ;)
Boh. Per me rimane sbagliato.

akyra
11-09-2008, 11:11
lo sapevo....Brainfuck (http://it.wikipedia.org/wiki/Brainfuck) rimane illeso da qualsiasi critica...non poteva essere altrimenti :asd:

cosa c'è di più espressivo, di più soddisfacente di un "hello world" in brainfuck??


++++++++++
[
>+++++++>++++++++++>+++>+<<<<-
]
>++.
>+. e
+++++++. l
. l
+++. o
>++.
<<+++++++++++++++.
>.
+++.
------.
--------.
>+.
>.

mik93
11-09-2008, 11:16
sicuro che mi convenga? col tempo mi son scordato pure l'html (tranne i tag necessari come link link con immagine, grassetto ecc.) e inoltre una bella ripassata al css e una guardatina al flash la farei volentieri!

banryu79
11-09-2008, 13:01
lo sapevo....Brainfuck (http://it.wikipedia.org/wiki/Brainfuck) rimane illeso da qualsiasi critica...non poteva essere altrimenti :asd:
[cut]

Brainfuck è... perfetto :O
Fa esattamente quello che il suo nome promette: ti fotte il cervello :D

shinya
11-09-2008, 14:05
Boh. Per me rimane sbagliato.

Devi capire che la filosofia di base è "we're all consenting adults here" (http://groups.google.com/group/comp.lang.python/browse_thread/thread/dad0361902521632/ed40457da2dc10b2?lnk=st&q=%22we%27re+all+consenting+adults+here%22+python&rnum=2&hl=en#ed40457da2dc10b2).

In python puoi aggiungere un doppio underscore davanti a variabili/metodi per renderli "privati"... ma in realtà non rendi privato niente.
So che può sembrare sconcertante, se si viene solo da java.

cdimauro
11-09-2008, 14:14
Boh. Per me rimane sbagliato.
In tal caso aggiungilo alla sezione Python di quel wiki. ;)

banryu79
11-09-2008, 14:39
Boh. Per me rimane sbagliato.
E tanto per dirne una: anche se in SmallTalk essite il "concetto" di variabile privata come in Python non è previsto un meccanismo esplicito per renderla tale; come in Python, ci si affida ad una coding convention (pure per i metodi "privati" di una classe, per distinguerli da quelli pubblici vengono raggruppati in un apposito protocollo [i protocolli in SmallTalk sono un sitema per dividere "concettualmente" i metodi di una classe in aree specifiche/funzionali e vengono usati anche per altri scopi]).

shinya
11-09-2008, 15:05
Ah! Poi anche in java il concetto di 'privato' è un pò labile...

Esempio scritto in 5 minuti:

// NotReallyPrivate.java
class NotReallyPrivate {
private int i = 666;
private String s = "Hello World!";
}

// HackPrivate.java
class HackPrivate {
public static void main(final String[] args) throws Exception {
NotReallyPrivate victim = new NotReallyPrivate();
Field[] fields = victim.getClass().getDeclaredFields();

for (Field f : fields) {
f.setAccessible(true);

if (f.getType().getName().equals("int")) {
out.println(f + " = " + f.getInt(victim));
f.setInt(victim, 42);
out.println(f + " = " + f.getInt(victim));
} else {
out.println(f + " = " + f.get(victim));
f.set(victim, "OMG!!1");
out.println(f + " = " + f.get(victim));
}
}
}
}

Output:
C:\tmp\>javac *.java

C:\tmp\>java HackPrivate
private int NotReallyPrivate.i = 666
private int NotReallyPrivate.i = 42 <-- Ma non era "private"???
private java.lang.String NotReallyPrivate.s = Hello World!
private java.lang.String NotReallyPrivate.s = OMG!!1 <-- e questo??

magix2003
11-09-2008, 15:05
Per quello che ne so in SmallTalk ogni variabile è sempre privata e ogni metodo è sempre pubblica..

k0nt3
11-09-2008, 15:22
avrei qualcosa da recriminare a python :asd:

1) not ha una priorità più bassa dell'operatore ==
CONSEGUENZE:
not a == b è interpretato come not (a == b) a differenza della gran parte dei linguaggi (esistono altri linguaggi con questo comportamento?) mentre a == not b è un errore di sintassi

2) gli operatori and e or non restituiscono True o False, ma il valore di uno degli operandi in accordo con la seguente tabella:
x or y if x is false, then y, else x
x and y if x is false, then x, else y
CONSEGUENZE:
>>> 'a' == ('a' and 'b')
False
>>> 'a' == ('b' and 'a')
True

abbastanza illeggibile :fagiano:

3) gli operatori <> e != sono equivalenti quindi non si spiega il fatto che esistono tutti e due

ecco ora mi disiscrivo dalla discussione altrimenti è finita! :Prrr:

cdimauro
11-09-2008, 15:54
Il punto 3 lo potrai depennare fra un mesetto circa, quando uscirà la final di Python 3.0. :cool:

Sul punto 2 abbiamo già discusso e ti ho mostrato come sia molto utile nella stragrande maggioranza dei casi in cui si utilizzano questi operatori logici (ossia: prendere decisioni anziché calcolare il valore booleano dell'operazione).
Inoltre... non restituisce booleani, a meno che non lo sia qualche argomento. Se proprio vuoi ottenere dei booleani, puoi sempre mettere usare il costruttore bool a cui passare gli operandi, ma... sono sicurissimo che nessuno lo userà mai nella stragrande maggioranza dei casi, per quanto scritto (servono per prendere decisioni, non per calcolare i relativi valori booleani). :cool: :cool: :cool:

Sul punto 1 hai ragione: il not è a priorità più bassa. Può piacere o meno, dipende dai gusti e da come si scrive il codice.

In ogni caso ti aspetta la paginetta sul wiki da aggiornare. ;)

shinya
11-09-2008, 16:07
In riferimento al post che ho scritto prima... ho cambiato la classe con i campi privati mettendoli final, e...


// NotReallyPrivate.java
class NotReallyPrivate {
private final int i = 666;
private final String s = "Hello World!";
}

// la classe HackPrivate rimane uguale a prima...

C:\tmp>java HackPrivate
private final int NotReallyPrivate.i = 666
private final int NotReallyPrivate.i = 42
private final java.lang.String NotReallyPrivate.s = Hello World!
private final java.lang.String NotReallyPrivate.s = OMG!!1


Cioè, posso cambiare a runtime il contenuto di oggetti privati e costanti di un'istanza... questa non la sapevo... ma non ci avevano fatto una testa cosi con il security model, ecc...ecc...?

A cosa serve "private" e "final" se posso fare quello che ho fatto?

cdimauro
11-09-2008, 16:40
A nulla. :D

Sarebbe interessante sapere se in .NET ciò sia possibile (mi riferisco a C# e C++/CLR in particolare). :)

recoil
11-09-2008, 16:41
Cioè, posso cambiare a runtime il contenuto di oggetti privati e costanti di un'istanza... questa non la sapevo... ma non ci avevano fatto una testa cosi con il security model, ecc...ecc...?

A cosa serve "private" e "final" se posso fare quello che ho fatto?

uhm sì sapevo che si poteva fare, però la chiamava a setAccessible può generare un'eccezione legata alla sicurezza.
non so come funziona, ma credo sia possibile proteggere una classe o dei campi in modo da non consentire alla setAccessible di renderli disponibili a chiunque

magari qualcuno lo sa e ci toglie il dubbio.

k0nt3
11-09-2008, 16:58
Ah! Poi anche in java il concetto di 'privato' è un pò labile...

Esempio scritto in 5 minuti:

// NotReallyPrivate.java
class NotReallyPrivate {
private int i = 666;
private String s = "Hello World!";
}

// HackPrivate.java
class HackPrivate {
public static void main(final String[] args) throws Exception {
NotReallyPrivate victim = new NotReallyPrivate();
Field[] fields = victim.getClass().getDeclaredFields();

for (Field f : fields) {
f.setAccessible(true);

if (f.getType().getName().equals("int")) {
out.println(f + " = " + f.getInt(victim));
f.setInt(victim, 42);
out.println(f + " = " + f.getInt(victim));
} else {
out.println(f + " = " + f.get(victim));
f.set(victim, "OMG!!1");
out.println(f + " = " + f.get(victim));
}
}
}
}

Output:
C:\tmp\>javac *.java

C:\tmp\>java HackPrivate
private int NotReallyPrivate.i = 666
private int NotReallyPrivate.i = 42 <-- Ma non era "private"???
private java.lang.String NotReallyPrivate.s = Hello World!
private java.lang.String NotReallyPrivate.s = OMG!!1 <-- e questo??


come dice la parola stessa è un hack :p
usare i campi private significa dire che è meglio non accedere a questi campi direttamente, perchè l'oggetto potrebbe trovarsi in una situazione inconsistente.
se poi uno non vuole ascoltare lo fa a suo rischio e pericolo, gli hack esistono per qualsiasi cosa.

cdimauro
11-09-2008, 17:08
In Delphi e C++ non puoi usare hack per accedere ai campi privati: soltanto per quelli protected.

In ogni caso se alla fine questi campi sono accessibili, non ha nemmeno senso sentenziare su Python che offre già di default e in maniera trasparente all'utente un meccanismo simile. ;)

shinya
11-09-2008, 17:14
uhm sì sapevo che si poteva fare, però la chiamava a setAccessible può generare un'eccezione legata alla sicurezza.
non so come funziona, ma credo sia possibile proteggere una classe o dei campi in modo da non consentire alla setAccessible di renderli disponibili a chiunque

magari qualcuno lo sa e ci toglie il dubbio.

Si no vabbeh, se lanci l'interprete con il security manager non funziona più...
Voglio dire:

java -Djava.security.manager HackPrivate

e lancia un'eccezione alla setAccessible... mi stupivo del fatto che non fosse il comportamento di default.


In ogni caso se alla fine questi campi sono accessibili, non ha nemmeno senso sentenziare su Python che offre già di default e in maniera trasparente all'utente un meccanismo simile.


Si, volevo poi arrivare li con il discorso :)

k0nt3
11-09-2008, 17:19
In Delphi e C++ non puoi usare hack per accedere ai campi privati: soltanto per quelli protected.

In ogni caso se alla fine questi campi sono accessibili, non ha nemmeno senso sentenziare su Python che offre già di default e in maniera trasparente all'utente un meccanismo simile. ;)
diciamo che se uno ci fa l'abitudine in python usa i campi privati e non privati come se fossero la stessa cosa. rendere il procedimento più difficile significa scoraggiare questo comportamento e la cosa è riuscita benissimo con java visto che normalmente non si usano questi hack, mentre in python talvolta si usa, tanto basta mettere un doppio underscore :fagiano:
tra l'altro è bruttissimo sto doppio underscore, non so a chi è venuto in mente :muro:

ps. in c++ non si possono modificare nemmeno andando a sovrascrivere la memoria con dei puntatori?

cdimauro
11-09-2008, 17:31
diciamo che se uno ci fa l'abitudine in python usa i campi privati e non privati come se fossero la stessa cosa. rendere il procedimento più difficile significa scoraggiare questo comportamento e la cosa è riuscita benissimo con java visto che normalmente non si usano questi hack, mentre in python talvolta si usa, tanto basta mettere un doppio underscore :fagiano:
E' la stessa identica pratica usata per i campi / metodi protected di linguaggi come C++, Delphi, Java, ecc. Né più né meno.
tra l'altro è bruttissimo sto doppio underscore, non so a chi è venuto in mente :muro:
Si usa anche in altri linguaggi l'underscore per segnalare identificatori particolari.
ps. in c++ non si possono modificare nemmeno andando a sovrascrivere la memoria con dei puntatori?
Certo che sì, ma devi conoscere in maniera pratica in che modo il compilatore genera la struttura dell'oggetto (cioé gli offset ai dati e ai metodi)...

Hiskrtapps
11-09-2008, 19:26
Devi capire che la filosofia di base è "we're all consenting adults here" (http://groups.google.com/group/comp.lang.python/browse_thread/thread/dad0361902521632/ed40457da2dc10b2?lnk=st&q=%22we%27re+all+consenting+adults+here%22+python&rnum=2&hl=en#ed40457da2dc10b2).

In python puoi aggiungere un doppio underscore davanti a variabili/metodi per renderli "privati"... ma in realtà non rendi privato niente.
So che può sembrare sconcertante, se si viene solo da java.
Non è sconcerto.. è che io non sono d'accordo con il lasciare certe cose solo al buon senso e alla pratica comune perchè questo comporta rischi.
Ci sono persone che programmano in un certo modo e altre in un altro modo.
Il non poter accedere a costanti private fa si che ci sia una omologazione guidata dal linguaggio e questo è solo un bene.
Per dirla tutta, credo che sia molto peggio questo fatto che l'uso dell'indentazione al posto delle parentesi il che, sebbene pedante, costringe a lavorare tutti nello stesso modo e quindi per quanto possa non piacere si basa su un principio giusto.

Per quanto riguarda l'utilizzo della reflection in java per aggirare l'ostacolo serve perchè in alcuni casi non si può fare altrimenti (esempio, per unità di test o di ottimizzazione) ma non è decisamente la stessa cosa(non credo che nessuno scriva programmi invocando tutti i metodi via reflection); cioè non si può semplificare dicendo: beh, tanto puoi farlo in un modo allora tanto vale permetterlo.
Prima di tutto perchè l'invocazione di un metodo via reflection costa circa 4-5 volte l'invocazione diretta, e secondo perchè è chiaro che in qualunque linguaggio basterebbe mettere mano al compilatore o all'interprete per aggirare qualsiasi ostacolo. E se anche via reflection non fosse stato possibile, bastava intervenire direttamente sul bytecode.

shinya
11-09-2008, 20:44
Non è sconcerto.. è che io non sono d'accordo con il lasciare certe cose solo al buon senso e alla pratica comune perchè questo comporta rischi.
Ci sono persone che programmano in un certo modo e altre in un altro modo.
Il non poter accedere a costanti private fa si che ci sia una omologazione guidata dal linguaggio e questo è solo un bene.


Mah... che sia un bene non saprei.
Questa convinzione da romanzo orwelliano che il linguaggio dovrebbe dirmi come devo programmare non l'ho mai condivisa. È lo stesso motivo per cui in java non esiste l'operator overloading...un'altra cazzata immane.


Per quanto riguarda l'utilizzo della reflection in java per aggirare l'ostacolo serve perchè in alcuni casi non si può fare altrimenti (esempio, per unità di test o di ottimizzazione) ma non è decisamente la stessa cosa(non credo che nessuno scriva programmi invocando tutti i metodi via reflection)

Ottimizzazione?? Per esempio?
Scusa ma poi non stai cadendo in contraddizione? Prima dici che X è un male in assoluto, e poi dici che senza X non si può fare altrimenti...
Il fatto che si possa fare, permette ad un programmatore PincoPallo di scrivere codice in uno stile che il linguaggio dovrebbe "proibire". Chi mi vieta di scrivere una libreria per accedere agevolmente ai campi privati di una classe, evitando di scrivere quello schifo di codice?
Anzi...in realtà c'è già qualcosa: http://fest.easytesting.org/reflect/

k0nt3
11-09-2008, 20:44
E' la stessa identica pratica usata per i campi / metodi protected di linguaggi come C++, Delphi, Java, ecc. Né più né meno.

vuoi dire che posso accedere a campi dichiarati protected da dove mi pare con una notazione tipo object.__protectedField ?

Kralizek
11-09-2008, 21:28
Probabile. :D

Mi pare di ricordare che in Visual Basic ci fosse qualcosa di lontanamente simile (anche se con un significato diverso):
With <Oggetto>
.Proprietà = Valore
.Metodo()
End With

Magari potevano riciclare la keyword per questo scopo e togliere l'ambiguità... :)

posso fare il pignolo?

In VB.NET:

With <Oggetto>
.Proprietà = Valore
.Metodo()
End With

permette di accedere "velocemente" ai metodi di un oggetto,

ma:


Using conn As DbConnection = factory.CreateConnection()
....
End Using


ha lo stesso significato che in C# ;)

cdimauro
11-09-2008, 22:18
vuoi dire che posso accedere a campi dichiarati protected da dove mi pare con una notazione tipo object.__protectedField ?
Ti dirò di più: puoi usare un oggetto come se tutti i suoi membri protected fossero pubblici. :D

Ecco qua, in (pseudo)Delphi:
var
x: TProtectedClass := TProtectedClass.Create();

type
class TProtectedClassCracker(TProtectedClass);

with TProtectedClassCracker(x) do begin
MioCampoProtetto := 'Crackato!!!';
MiaFunzioneProtetta('Anche per te non c'è nulla da fare: crackata!!!');
end;
Dove TProtectedClass è una classe definita in un'altra unit, e i cui membri protected quindi non sono assolutamente accessibili da una sua qualunque istanza. :cool:

k0nt3
12-09-2008, 01:59
Ti dirò di più: puoi usare un oggetto come se tutti i suoi membri protected fossero pubblici. :D

Ecco qua, in (pseudo)Delphi:
var
x: TProtectedClass := TProtectedClass.Create();

type
class TProtectedClassCracker(TProtectedClass);

with TProtectedClassCracker(x) do begin
MioCampoProtetto := 'Crackato!!!';
MiaFunzioneProtetta('Anche per te non c'è nulla da fare: crackata!!!');
end;
Dove TProtectedClass è una classe definita in un'altra unit, e i cui membri protected quindi non sono assolutamente accessibili da una sua qualunque istanza. :cool:

non mi sembra che ci sia niente di strano, questo comportamento è descritto nelle specifiche del linguaggio (parlo di Java perchè Delphi non lo conosco molto).
se vuoi che ciò non sia possibile basta che ometti il modificatore al posto di mettere protected. in questo modo il campo è visibile solo all'interno del package anche per le sottoclassi

cdimauro
12-09-2008, 08:11
non mi sembra che ci sia niente di strano, questo comportamento è descritto nelle specifiche del linguaggio (parlo di Java perchè Delphi non lo conosco molto).
Dove sta scritto che posso tranquillamente accedere ai membri protected da un'istanza della stessa classe?
se vuoi che ciò non sia possibile basta che ometti il modificatore al posto di mettere protected. in questo modo il campo è visibile solo all'interno del package anche per le sottoclassi
protected esiste perché chi ha creato la classe vuole che i membri dichiarati in questo modo siano visibili nelle sottoclassi che la estendono. Altrimenti avrebbe usato private, non credi?

Hiskrtapps
12-09-2008, 10:37
Mah... che sia un bene non saprei.
Questa convinzione da romanzo orwelliano che il linguaggio dovrebbe dirmi come devo programmare non l'ho mai condivisa.

Beh, la pensiamo diversamente.
Per me la creatività dello sviluppatore non sta certo in come accede ai campi (quello dovrebbe essere uguale per tutti);
Impedire di accedere a un campo perchè privato non mi sta mica dicendo come devo programmare.
Ottimizzazione?? Per esempio?
Scusa ma poi non stai cadendo in contraddizione? Prima dici che X è un male in assoluto, e poi dici che senza X non si può fare altrimenti...
Il fatto che si possa fare, permette ad un programmatore PincoPallo di scrivere codice in uno stile che il linguaggio dovrebbe "proibire". Chi mi vieta di scrivere una libreria per accedere agevolmente ai campi privati di una classe, evitando di scrivere quello schifo di codice?
Anzi...in realtà c'è già qualcosa: http://fest.easytesting.org/reflect/

Con ottimizzazione intendevo qualche tool in grado di vedere oggetti istanziati, memoria occupata e robe per consentire la profilazione di un programma.
(mi ero spiegato davvero male, sorry!)
Cmq nessuno ti vieta di scrivere quella libreria chiaramente (che infatti hanno scritto, visto che mi hai dato il link :-D); ora però l'utilizzo di quella ilibreria presuppone che a compile time non sei in grado di sapere se stai invocando qualche metodo inesistente, o lo stai facendo con parametri sbagliati (non hai più il type check), per non parlare poi delle performance; quindi direi proprio che non si può dire che java consente l'accesso alle variabili private allo stesso modo che a quelle pubbliche.

k0nt3
12-09-2008, 10:56
Dove sta scritto che posso tranquillamente accedere ai membri protected da un'istanza della stessa classe?

ma infatti accedi ai campi tramite un'istanza di un'altra classe.

ps. quella sintassi indica che TProtectedClassCracker è sottoclasse di TProtectedClass giusto?

protected esiste perché chi ha creato la classe vuole che i membri dichiarati in questo modo siano visibili nelle sottoclassi che la estendono. Altrimenti avrebbe usato private, non credi?
parlo di Java visto che tu hai detto che Delphi e Java usano la stessa pratica per i campi protected.

protected esiste perchè chi ha creato la classe vuole che i membri siano visibili all'interno dello stesso package e nelle sottoclassi (anche fuori dal package).

il modificatore di default invece rende visibili i campi solo all'interno dello stesso package (e quindi non nelle sottoclassi fuori dal package).

ma quindi la risposta alla mia precedente domanda era: no, cioè non si puo' invocare metodi protetti con una roba tipo object.__protectedMethod()
quindi Java non usa la stessa pratica che Python usa per i campi privati

ps. un'altra possibilità è quella di usare il modificatore final per dichiarare la classe. in questo modo non si può ereditare da quella classe, così i campi protected sicuramente non escono dal package

cdimauro
12-09-2008, 14:38
ma infatti accedi ai campi tramite un'istanza di un'altra classe.
Eh no: accedo ai campi di un'istanza di TProtectedClass, ma sfruttando un'altra classe (quella che funge da "cracker").
ps. quella sintassi indica che TProtectedClassCracker è sottoclasse di TProtectedClass giusto?
Sì.
parlo di Java visto che tu hai detto che Delphi e Java usano la stessa pratica per i campi protected.

protected esiste perchè chi ha creato la classe vuole che i membri siano visibili all'interno dello stesso package e nelle sottoclassi (anche fuori dal package).

il modificatore di default invece rende visibili i campi solo all'interno dello stesso package (e quindi non nelle sottoclassi fuori dal package).
Quindi mi stai dicendo che dichiarando come protected il membro di una classe che risiede in un package, questo non sarà visibile da una sottoclasse che non sta nel package?
ma quindi la risposta alla mia precedente domanda era: no, cioè non si puo' invocare metodi protetti con una roba tipo object.__protectedMethod()
quindi Java non usa la stessa pratica che Python usa per i campi privati
Chiaro che no. In Python si usa il name mangling per definiare un oggetto "privato" nei confronti dell'esportazione, ma vi puoi sempre accedere (e anche importarlo, specificandolo direttamente).
ps. un'altra possibilità è quella di usare il modificatore final per dichiarare la classe. in questo modo non si può ereditare da quella classe, così i campi protected sicuramente non escono dal package
Ma non è questo il punto. Il punto è che dichiaro protected un membro, non è affatto vero che non sarà più accessibile se non da una sottoclasse, perché la protezione può essere tranquillamente aggirata.

k0nt3
12-09-2008, 16:31
Eh no: accedo ai campi di un'istanza di TProtectedClass, ma sfruttando un'altra classe (quella che funge da "cracker").
e cosa ho detto io? :fagiano:

Quindi mi stai dicendo che dichiarando come protected il membro di una classe che risiede in un package, questo non sarà visibile da una sottoclasse che non sta nel package?

no, l'esatto contrario

Chiaro che no. In Python si usa il name mangling per definiare un oggetto "privato" nei confronti dell'esportazione, ma vi puoi sempre accedere (e anche importarlo, specificandolo direttamente).

quindi in che senso dicevi che in C++ Java e Delphi si usa la stessa pratica che si usa in python per i campi privati?

Ma non è questo il punto. Il punto è che dichiaro protected un membro, non è affatto vero che non sarà più accessibile se non da una sottoclasse, perché la protezione può essere tranquillamente aggirata.

intendi aggirare la protezione usando una sottoclasse? :confused:
secondo me significa solo attenersi alle specifiche.
prendo le specifiche di Java così è più facile spiegarlo:

if the member or constructor is declared protected, then access is permitted only when one of the following is true:

o Access to the member or constructor occurs from within the package containing the class in which the protected member or constructor is declared.
o Access is correct as described in §6.6.2.


dove nel paragrafo 6.6.2 si dice che:

6.6.2 Details on protected Access
A protected member or constructor of an object may be accessed from outside the package in which it is declared only by code that is responsible for the implementation of that object.

6.6.2.1 Access to a protected Member
Let C be the class in which a protected member m is declared. Access is permitted only within the body of a subclass S of C. In addition, if Id denotes an instance field or instance method, then:

* If the access is by a qualified name Q.Id, where Q is an ExpressionName, then the access is permitted if and only if the type of the expression Q is S or a subclass of S.
* If the access is by a field access expression E.Id, where E is a Primary expression, or by a method invocation expression E.Id(. . .), where E is a Primary expression, then the access is permitted if and only if the type of E is S or a subclass of S.


in pratica se vuoi che i campi siano visibili solo all'interno del package, ma non vuoi che siano visibili alle sottoclassi, basta che usi il modificatore di default anzichè protected. perchè con protected chiaramente sono visibili alle sottoclassi

cdimauro
12-09-2008, 20:44
e cosa ho detto io? :fagiano:
Che si accede ai campi tramite l'istanza di un'altra classe. Invece si accede ai campi di un'istanza tramite un'altra classe. ;)
no, l'esatto contrario
OK
quindi in che senso dicevi che in C++ Java e Delphi si usa la stessa pratica che si usa in python per i campi privati?
Parlavo dei metodi protected. Comunque con la "pratica" mi riferivo al fatto che Python permette di nascondere dei membri, ma non impedisce di accedervi. Similmente ai linguaggi di cui sopra, che nascondono dei membri dietro l'uso di protected, ma ciò non impedisce comunque di accedervi.
intendi aggirare la protezione usando una sottoclasse? :confused:
Esattamente.
secondo me significa solo attenersi alle specifiche.
prendo le specifiche di Java così è più facile spiegarlo:

dove nel paragrafo 6.6.2 si dice che:

in pratica se vuoi che i campi siano visibili solo all'interno del package, ma non vuoi che siano visibili alle sottoclassi, basta che usi il modificatore di default anzichè protected. perchè con protected chiaramente sono visibili alle sottoclassi
Come puoi vedere le specifiche vengono abilmente aggirate con quel trucchetto. Il nocciolo della questione sta tutto qui:

A protected member or constructor of an object may be accessed from outside the package in which it is declared only by code that is responsible for the implementation of that object.

L'intento è chiaramente quello di permettere la manipolazione dei membri protected soltanto dal codice della classe o delle sue sottoclassi. Cosa che è rimarcata anche qui:

Let C be the class in which a protected member m is declared. Access is permitted only within the body of a subclass S of C.

Ma tutto ciò viene disatteso nei successivi punti, quando si permette di utilizzare delle espressioni il cui risultato finale sia del tipo della classe base o delle sue derivate. Infatti con un banale cast che usa una classe "cracker" di fatto si rendono pubblici tutti i membri protected di una classe.

Con questo meccanismo l'uso di protected è tranquillamente aggirato: è come se fosse public.

k0nt3
13-09-2008, 12:18
premessa: è probabile che non abbia capito perfettamente quello che intendi, quindi fammelo sapere nel caso :p
Che si accede ai campi tramite l'istanza di un'altra classe. Invece si accede ai campi di un'istanza tramite un'altra classe. ;)

in pratica quello che stiamo dicendo tutti e due è che si accede ai campi di un'istanza tramite l'istanza di un'altra classe.

Parlavo dei metodi protected. Comunque con la "pratica" mi riferivo al fatto che Python permette di nascondere dei membri, ma non impedisce di accedervi. Similmente ai linguaggi di cui sopra, che nascondono dei membri dietro l'uso di protected, ma ciò non impedisce comunque di accedervi.
non è vero, puoi accedervi solo nei casi stabiliti dalle specifiche, non sempre

Esattamente.

Come puoi vedere le specifiche vengono abilmente aggirate con quel trucchetto. Il nocciolo della questione sta tutto qui:

A protected member or constructor of an object may be accessed from outside the package in which it is declared only by code that is responsible for the implementation of that object.

L'intento è chiaramente quello di permettere la manipolazione dei membri protected soltanto dal codice della classe o delle sue sottoclassi. Cosa che è rimarcata anche qui:

Let C be the class in which a protected member m is declared. Access is permitted only within the body of a subclass S of C.

Ma tutto ciò viene disatteso nei successivi punti, quando si permette di utilizzare delle espressioni il cui risultato finale sia del tipo della classe base o delle sue derivate. Infatti con un banale cast che usa una classe "cracker" di fatto si rendono pubblici tutti i membri protected di una classe.

Con questo meccanismo l'uso di protected è tranquillamente aggirato: è come se fosse public.
non mi sembra che funzioni così in Java.
mettiamo di avere una classe che si chiama Classe1 che è nel package pack1 e vuole accedere a un campo protected di una certa Classe2 nel package pack2
Classe2 è la seguente:

package pack2;

public class Classe2 {
protected String str = "sono protetto!";
}

secondo il tuo procedimento dovrei creare una classe che estende Classe2 nel package pack1:

package pack1;

import pack2.Classe2;

public class Classe2bis extends Classe2 {

@Override
public String toString() {
return this.str;
}
}

come puoi notare questa classe può accedere al campo protected poichè estende Classe2.
ora non mi resta che chiamare questo metodo in Classe1:

package pack1;

import pack2.Classe2;

public class Classe1 {

public static void main(String[] args) {
Classe2bis c2 = new Classe2bis();
System.out.println(c2.toString());
}

}

qui si possono fare 3 osservazioni:
- non è possibile in alcun modo in Classe1 accedere direttamente a c2.str come se fosse public, il compilatore da errore.

- non è affatto vero che protected è inutile, perchè non può essere sempre aggirato. ad esempio nel caso in cui non hai a disposizione la classe base, ma solo un'interfaccia, non puoi estenderla e quindi non puoi in nessun modo accedere ai campi protected. ti assicuro che questo avviene molto spesso in sistemi abbastanza complessi.

- se chi ha progettato il software non vuole che questo comportamento sia possibile è sufficiente che al posto di dichiarare il campo Classe2.str protected lasci il modificatore di default:

package pack2;

public class Classe2 {
String str = "sono protetto!";
}

in questo caso Classe2bis così come è scritta sopra non compila perchè il campo str non è visibile.

come vedi si ha un ventaglio di possibilità molto ampio, tutto è a discrezione di chi progetta il software.

k0nt3
13-09-2008, 12:23
in ogni caso secondo me python non deve avere i modificatori come java.
se li avesse non sarebbe python, ma java. va bene così, ogni linguaggio si addice a certi scopi

EDIT: anzi secondo me non dovrebbe avere quella pseudo-implementazione dei campi privati, sembra un hack messo lì per accontentare qualcuno. non è per niente elegante

cdimauro
13-09-2008, 12:54
premessa: è probabile che non abbia capito perfettamente quello che intendi, quindi fammelo sapere nel caso :p
OK :D
in pratica quello che stiamo dicendo tutti e due è che si accede ai campi di un'istanza tramite l'istanza di un'altra classe.
No, si accede ai campi dell'istanza di una classe, tramite un'altra classe.
non è vero, puoi accedervi solo nei casi stabiliti dalle specifiche, non sempre

non mi sembra che funzioni così in Java.
mettiamo di avere una classe che si chiama Classe1 che è nel package pack1 e vuole accedere a un campo protected di una certa Classe2 nel package pack2
Classe2 è la seguente:

package pack2;

public class Classe2 {
protected String str = "sono protetto!";
}

secondo il tuo procedimento dovrei creare una classe che estende Classe2 nel package pack1:

package pack1;

import pack2.Classe2;

public class Classe2bis extends Classe2 {

@Override
public String toString() {
return this.str;
}
}

come puoi notare questa classe può accedere al campo protected poichè estende Classe2.
ora non mi resta che chiamare questo metodo in Classe1:

package pack1;

import pack2.Classe2;

public class Classe1 {

public static void main(String[] args) {
Classe2bis c2 = new Classe2bis();
System.out.println(c2.toString());
}

}

qui si possono fare 3 osservazioni:
- non è possibile in alcun modo in Classe1 accedere direttamente a c2.str come se fosse public, il compilatore da errore.
Aspetta un attimo. Io farei come con Delphi, così:
package pack1;

import pack2.Classe2;

public class Classe2bis extends Classe2 {
// Nessun override! Semplicemente si estende Classe2.
}

public class Classe1 {

public static void main(String[] args) {
Classe2 c2 = new Classe2();
System.out.println((Classe2bis c2).str);
}

}

Dici che il compilatore mi sputa in faccia? :D
- non è affatto vero che protected è inutile, perchè non può essere sempre aggirato. ad esempio nel caso in cui non hai a disposizione la classe base, ma solo un'interfaccia, non puoi estenderla e quindi non puoi in nessun modo accedere ai campi protected. ti assicuro che questo avviene molto spesso in sistemi abbastanza complessi.
Lo so. Non è sempre applicabile.
- se chi ha progettato il software non vuole che questo comportamento sia possibile è sufficiente che al posto di dichiarare il campo Classe2.str protected lasci il modificatore di default:

package pack2;

public class Classe2 {
String str = "sono protetto!";
}

in questo caso Classe2bis così come è scritta sopra non compila perchè il campo str non è visibile.
Chiaro.
come vedi si ha un ventaglio di possibilità molto ampio, tutto è a discrezione di chi progetta il software.
Appunto, ma alcune "discrezioni" possono essere aggirate. ;)
in ogni caso secondo me python non deve avere i modificatori come java.
se li avesse non sarebbe python, ma java. va bene così, ogni linguaggio si addice a certi scopi
Perfettamente d'accordo. :)
EDIT: anzi secondo me non dovrebbe avere quella pseudo-implementazione dei campi privati, sembra un hack messo lì per accontentare qualcuno. non è per niente elegante
Non è un hack: è una funzionalità che riguarda esclusivamente l'esportazione dei campi.

Poi gli underscore li usano anche altri linguaggi per definire simboli speciali e/o regole di visibilità, ecc. ;)

k0nt3
13-09-2008, 13:38
Aspetta un attimo. Io farei come con Delphi, così:
package pack1;

import pack2.Classe2;

public class Classe2bis extends Classe2 {
// Nessun override! Semplicemente si estende Classe2.
}

public class Classe1 {

public static void main(String[] args) {
Classe2 c2 = new Classe2();
System.out.println((Classe2bis c2).str);
}

}

Dici che il compilatore mi sputa in faccia? :D


certo che ti sputa in faccia :Prrr:
Classe1 non estende Classe2 e non è nello stesso package di Classe2, quindi il campo str non è visibile. è visibile solo dentro Classe2bis perchè è una sottoclasse di Classe2 anche se è in un package diverso

cdimauro
13-09-2008, 14:16
OK, grazie per il chiarimento. Quindi Java non si comporta come Delphi e C++ in questi casi, che rendono molto facile l'accesso ai membri protected tramite l'uso dei cracker.

Anche con Java è sempre possibile farlo, ma, richiede più lavoro (serve creare una classe appositamente che faccia questo "sporco" lavoro).

k0nt3
13-09-2008, 14:19
esatto. in ogni caso ho imparato qualcosa di nuovo su C++ :cool: un altro motivo per evitarlo :asd:

71104
14-09-2008, 22:41
esatto. in ogni caso ho imparato qualcosa di nuovo su C++ :cool: un altro motivo per evitarlo :asd: ehm... :fagiano:
non so se ho capito bene perché la discussione era lunga, ma mi pare di capire che si sia giunti alla (falsissima) conclusione che questo codice C++ sia corretto:

#include <iostream>
using namespace std;

class Class1
{
protected:
int Member; // inizializzato da qualche costruttore

};

class Class2 : public Class1 {};

int main()
{
cout << Class2().Member << endl;
return 0;
}

k0nt3
14-09-2008, 22:57
ehm... :fagiano:
non so se ho capito bene perché la discussione era lunga, ma mi pare di capire che si sia giunti alla (falsissima) conclusione che questo codice C++ sia corretto:

#include <iostream>
using namespace std;

class Class1
{
protected:
int Member; // inizializzato da qualche costruttore

};

class Class2 : public Class1 {};

int main()
{
cout << Class2().Member << endl;
return 0;
}


beh allora solo delphi si comporta in quel modo ignobile :O

cdimauro
14-09-2008, 23:07
ehm... :fagiano:
non so se ho capito bene perché la discussione era lunga, ma mi pare di capire che si sia giunti alla (falsissima) conclusione che questo codice C++ sia corretto:

#include <iostream>
using namespace std;

class Class1
{
protected:
int Member; // inizializzato da qualche costruttore

};

class Class2 : public Class1 {};

int main()
{
cout << Class2().Member << endl;
return 0;
}

Alberto, ma non avevi detto tu tempo fa che i cracker funzionavano anche col C++? :read: :O

71104
14-09-2008, 23:10
questo è un cracker:

class Class1
{
protected:
virtual int Method();

};

class Class2 : public Class1
{
public:
int Method();

};

71104
14-09-2008, 23:17
questo è un cracker:
... vi precedo sulla freddura:
"no, questo è un cracker:"

http://www.cepolina.com/freephoto/f/other.food/cracker.snack.bread.jpg



... :stordita:

DanieleC88
15-09-2008, 08:08
vi precedo sulla freddura:
"no, questo è un cracker:"

http://www.cepolina.com/freephoto/f/other.food/cracker.snack.bread.jpg



... :stordita:
Ecco bravo, precedimi nel dire cazzate, così evito di spararle io. :asd: :Prrr:

marko.fatto
16-09-2008, 20:19
dato che il pezzo del php è abbastanza lungo :asd:
questo è già stato messo? :stordita:
<?php
$F = "F";
function F($s) { return $s; }
$name = 'asd';
echo "{$F($filename)}";
?>

cdimauro
16-09-2008, 21:23
Guarda che hai sbagliato: questo non è il thread sull'obfuscated code in PHP. :asd:

Traducilo in maniera comprensibile a un essere umano e, semmai dovesse mancare, sicuramente "qualcuno" aggiungerà la nuove voce nel wiki. :D

VICIUS
16-09-2008, 22:15
Guarda che hai sbagliato: questo non è il thread sull'obfuscated code in PHP. :asd:

Traducilo in maniera comprensibile a un essere umano e, semmai dovesse mancare, sicuramente "qualcuno" aggiungerà la nuove voce nel wiki. :D
È una semplice chiamata indiretta a funzione.

cdimauro
16-09-2008, 22:26
Sì, lo so (purtroppo con PHP c'ho dovuto lavorare per un po' di tempo :cry:): volevo soltanto che fosse Marco a darmi una spiegazione di quell'accrocco. :D

VICIUS
16-09-2008, 22:28
Sì, lo so (purtroppo con PHP c'ho dovuto lavorare per un po' di tempo :cry:): volevo soltanto che fosse Marco a darmi una spiegazione di quell'accrocco. :D
È consolante sapere che non sono l'unico che ha imparato ad odiare php :D

cdimauro
16-09-2008, 22:32
Proprio per questo bisogna diffondere la nostra grande considerazione nei confronti di questo bellissimo linguaggio. :asd:

DanieleC88
16-09-2008, 22:35
È consolante sapere che non sono l'unico che ha imparato ad odiare php :D
Ho ancora i tuoi tutorial su PHP... così, corrompevi le menti giovani ed innocenti come la mia al male, ed ora rinneghi, eh? :asd:

:Prrr:
(in effetti ora come ora preferirei anche io Python a PHP come linguaggio di scripting)

VICIUS
16-09-2008, 23:36
Ho ancora i tuoi tutorial su PHP... così, corrompevi le menti giovani ed innocenti come la mia al male, ed ora rinneghi, eh? :asd:

:Prrr:
(in effetti ora come ora preferirei anche io Python a PHP come linguaggio di scripting)
Sospeso 2 settimane per avermi fatto tornare in mente quelle orribili guide. :D

DanieleC88
16-09-2008, 23:54
:asd:

marko.fatto
17-09-2008, 00:03
scusate ero al cinema.. comunque si è come ha detto vicius solo che era venuto fuori quell'accrocchio chattando con un amico che è alle prese con php per un portale... sinceramente non mi sembra il massimo poter chiamare una funzione in quel modo ma lo dico solo così a naso perchè può avere anche la sua utilità :stordita: :fagiano:

VICIUS
17-09-2008, 00:53
scusate ero al cinema.. comunque si è come ha detto vicius solo che era venuto fuori quell'accrocchio chattando con un amico che è alle prese con php per un portale... sinceramente non mi sembra il massimo poter chiamare una funzione in quel modo ma lo dico solo così a naso perchè può avere anche la sua utilità :stordita: :fagiano:
Se ti spaventa questo allora guarda cosa si può fare con qualche riga di ruby :D
# Apro la classe String e aggiungeo una funzione
class String
def prima_lettera()
self[0]
end

# poi cancello l'operatore del confronto perché sono cattivo!
undef <=>
end

mondo = String.new("mondo")

# ora aggiungo un singolo metodo ad una singola istanza della classe String
def mondo.saluta()
puts "Ciao #{self}!"
end

# stampa Ciao mondo!
mondo.saluta

# questo stampa "m"
puts mondo.prima_lettera

# questo lancia una eccezione perché sort usa l'operatore <=>
array = ['a', 'c', 'b', 'a']
array.sort!

marko.fatto
17-09-2008, 01:01
se non ricordo male anche in ruby si può fare una cosa simile a quella che ho postato in php no? :fagiano:

io proprio non capisco perchè dare la possibilità di fare una cosa simile? in che casi può essere utile? :mbe:

edit: in effetti non capisco anche l'utilità del poter rimuovere una funziona da una classe :fagiano:

cdimauro
17-09-2008, 08:11
Ho ancora i tuoi tutorial su PHP... così, corrompevi le menti giovani ed innocenti come la mia al male, ed ora rinneghi, eh? :asd:

:Prrr:
Poteva sospenderti anche per contestazione pubblica a un moderatore. :asd:
(in effetti ora come ora preferirei anche io Python a PHP come linguaggio di scripting)
[RASOIO DI OCCAM MODE ON]

in effetti preferirei anche io Python a PHP come linguaggio

[RASOIO DI OCCAM MODE OFF]

:O
scusate ero al cinema.. comunque si è come ha detto vicius solo che era venuto fuori quell'accrocchio chattando con un amico che è alle prese con php per un portale... sinceramente non mi sembra il massimo poter chiamare una funzione in quel modo ma lo dico solo così a naso perchè può avere anche la sua utilità :stordita: :fagiano:
Ha sicuramente la sua utilità. Il problema è la sintassi usata per realizzare tutto ciò. :muro:
Se ti spaventa questo allora guarda cosa si può fare con qualche riga di ruby :D
# Apro la classe String e aggiungeo una funzione
class String
def prima_lettera()
self[0]
end

# poi cancello l'operatore del confronto perché sono cattivo!
undef <=>
end

mondo = String.new("mondo")

# ora aggiungo un singolo metodo ad una singola istanza della classe String
def mondo.saluta()
puts "Ciao #{self}!"
end

# stampa Ciao mondo!
mondo.saluta

# questo stampa "m"
puts mondo.prima_lettera

# questo lancia una eccezione perché sort usa l'operatore <=>
array = ['a', 'c', 'b', 'a']
array.sort!
Riaprire le classi / istanze si può fare anche con Python, ma non per gli oggetti built-in e sicuramente non con una sintassi così elegante.

Il monkey patching è previsto, ma limitato.

Qui comunque ci sono correnti di pensiero diverse: c'è chi dice che è una buona cosa perché è uno strumento che permette una grande flessibilità, e c'è che dice che in questo modo si mina alle basi il "contratto" con chi deve usare quegli oggetti (per intenderci: un test case che si aspetta che funzioni l'operatore di confronto fallirebbe miseramente).
se non ricordo male anche in ruby si può fare una cosa simile a quella che ho postato in php no? :fagiano:

io proprio non capisco perchè dare la possibilità di fare una cosa simile? in che casi può essere utile? :mbe:
L'indirezione per l'invocazione di una funzione è sicuramente comoda, ma bisogna vedere in che modo la si realizza.

Ti faccio un esempio pratico:
def it(): return 'Ciao'

def en(): return 'Hello'

Saluto = it
print Saluto()

Saluto = en
print Saluto()
E' molto semplice, ma permette di capire che è possibile "indirizzare" una qualunque funzione e "portarsela dietro" nel codice passandola al altre funzioni e quant'altro.

Ma tutto ciò con una sintassi decisamente più elegante e comprensibile.
edit: in effetti non capisco anche l'utilità del poter rimuovere una funziona da una classe :fagiano:
L'utilità sta nel fatto che si può cambiare il comportamento di una classe a runtime. Che, come detto sopra, può essere un bene o un male a seconda dei punti di vista.

Un esempio banale è quello dell'abilitazione o meno del log:
import datetime
class c(object):

def __init__(self, Debug):
self.Log = self.LogEverything if Debug else self.EmptyLog

def LogEverything(self, *Args):
print datetime.datetime.now, ' '.join(Args)

def EmptyLog(self, *Args):
pass

def Work(self, x, y, z):
Log(x, y, z)

a = c(False)
a.Work(0, 1, 2) # Non stampa niente!!!

b = c(True)
a.Work(0, 1, 2) # Stampa data e ora corrente, e 0 1 2
In questo modo posso controllare il comportamento di un'istanza a runtime.

E' molto utile perché mi permette di evitare di creare n-mila classi che devono considerare le varie possibilità che ci possono essere a seconda delle variabili in gioco.

P.S. Ti ho fatto un esempio diverso da ciò che chiedevi, cioé la cancellazione di un metodo, perché è più semplice capire come modificare a runtime il comportamento di un'istanza. ;)

VICIUS
17-09-2008, 08:51
se non ricordo male anche in ruby si può fare una cosa simile a quella che ho postato in php no? :fagiano:
Certo. In ruby tutto è un oggetto. Blocchi di codice, funzioni, classi, moduli. In questo caso si usa un oggetto Method creato con il nome della funzione ed il suo metodo call. Come metodo è sicuramente più verboso e lungo di quello usato da php in cui basta una variabile ma io però preferisco l'approccio di ruby perché risulta più chiaro quello che si sta facendo.

io proprio non capisco perchè dare la possibilità di fare una cosa simile? in che casi può essere utile? :mbe:

edit: in effetti non capisco anche l'utilità del poter rimuovere una funziona da una classe :fagiano:
L'introspezione può essere usata per rendere più facile il compito del programmatore. Ad esempio in ruby non c'è alcun modo di accedere alle variabili di istanza di una classe dall'esterno. Se vuoi permettere la lettura e la modifica in una delle variabili sei quindi forzato a scrivere dei metodi. Ora visto che scrivere getter e setter è una palla assurda hanno pensato bene di scrivere un metodo che genera una coppia di funzioni get/set e le aggiunge alla classe corrente. Esempio:
class Punto
attr :x, :y

# bla bla bla ....
end

Oppure pensa al caso in cui la classe da cui eredita quella che stai scrivendo definisce una funzione che non ti serve oppure non è valida per la tua. Usi undef e non corri il rischio che qualcuno provi ad usarla. Un primo esempio che mi viene in mente è quella dei numeri complessi in cui l'operatore di confronto per l'ordinamento non ha senso.

Poteva sospenderti anche per contestazione pubblica a un moderatore. :asd:
Se lo avessi sospeso tutte le volte che mi ha ripreso la sospensione scadrebbe nel 2020 :asd:

DanieleC88
17-09-2008, 10:22
[RASOIO DI OCCAM MODE ON]

in effetti preferirei anche io Python a PHP come linguaggio

[RASOIO DI OCCAM MODE OFF]
LOL, giusta osservazione. :D
Se lo avessi sospeso tutte le volte che mi ha ripreso la sospensione scadrebbe nel 2020 :asd:
:eekk:

Su, andiamo, siete troppo cattivi. In fondo, sono o no un ballbreaker? :asd:

marko.fatto
17-09-2008, 12:57
ok grazie mille per le spiegazioni :D

71104
17-09-2008, 20:11
OT: "scusate ero al cinema" è bellissima :rotfl: :rotfl:

cdimauro
17-09-2008, 20:56
Mi sono accorto di aver commesso un errore madornale: nel secondo esempio dovevo invocare b.Work anziché a.Work. :muro:

Poco male: non se n'è accorto nessuno. :asd:

Mazzulatore
18-09-2008, 18:30
forse l'unico vero problema è che state appunto sucksando(passatemi il verbo :O ) solo i linguaggi che conoscete maggiormente e a leggere quella pagina sembra che si debba stare lontani da C++/Java quando invece sono le scelte più popolari(o quasi).
Esatto, quella pagina è pericolosa, il suo scopo è divertire, non MANIPOLARE le menti (ogni riferimento è puramente casuale :ciapet: ).
Guarda che sbagli: leggendo quella pagina si evince che bisogna star lontanissimi da PHP. :asd:
Se prendi il puro linguaggio, sono d'accordissimo, purtroppo tutt'oggi le offerte di hosting sono a favore di PHP e se consideri che molte delle applicazioni più famose e potenti sono in PHP per creare un plugin per Drupal o Joomla occorre conoscere... PHP. Comunque Java e ASP.Net sono in crescita (parlando di hosting)
Si può sempre supportare il multithreading senza allocare risorse in più per qualunque cosa. :fiufiu:
Ma cos'è sto syncronization monitor? un processo che prende il 100% della CPU? Oppure forse un banale reference (magari static, o shared a seconda della terminologia, cioè tutti gli oggetti ce l'hanno ma è un solo reference in tutta la JVM? Boh) all'oggetto che si incarica di gestire le direttive Syncronized?
Mi sembra molto poco per fare dei confronti di uso di risorse, poi sopratutto con PYTHON con cui ha poco da spartire.


In conclusione mi sembrava doveroso non lasciare tutto il thread in mano a Cdimauro e rompergli un po' le uova nel paniere, anche se non seguo più spesso il forum.

cdimauro
18-09-2008, 21:58
Esatto, quella pagina è pericolosa, il suo scopo è divertire, non MANIPOLARE le menti (ogni riferimento è puramente casuale :ciapet: ).
Io preferisco usarla per manipolare le menti. :Prrr:
Se prendi il puro linguaggio, sono d'accordissimo,
Mi sembra ovvio si parlasse del solo linguaggio. :O
purtroppo tutt'oggi le offerte di hosting sono a favore di PHP
Lo so, ma se ne cominciano a trovare anche per linguaggi diversi, per fortuna, e i prezzi sono pure abbordabili.
e se consideri che molte delle applicazioni più famose e potenti sono in PHP per creare un plugin per Drupal o Joomla occorre conoscere... PHP. Comunque Java e ASP.Net sono in crescita (parlando di hosting)
Non v'è dubbio, ma roba come Django e RoR si sta affermando sempre di più. Per lo meno si cominciano a vedere validissime alternative ai più blasonati prodotti realizzati in PHP.
Ma cos'è sto syncronization monitor? un processo che prende il 100% della CPU? Oppure forse un banale reference (magari static, o shared a seconda della terminologia, cioè tutti gli oggetti ce l'hanno ma è un solo reference in tutta la JVM? Boh) all'oggetto che si incarica di gestire le direttive Syncronized?
Mi sembra molto poco per fare dei confronti di uso di risorse, poi sopratutto con PYTHON con cui ha poco da spartire.
Come implementazione sicuramente. E per fortuna. :D

Se voglio sincronizzare l'accesso a dei dati preferisco decidere io quando e come allocare risorse in merito.
In conclusione mi sembrava doveroso non lasciare tutto il thread in mano a Cdimauro e rompergli un po' le uova nel paniere, anche se non seguo più spesso il forum.
Grazie per tutta questa grande importanza che mi dai, ma è un po' difficile che proprio tu riesca a rompermi le scatole, visti anche i precedenti che abbiamo avuto in altre sezioni. :read: :D :Prrr: :cool:

Mazzulatore
19-09-2008, 11:09
Se voglio sincronizzare l'accesso a dei dati preferisco decidere io quando e come allocare risorse in merito.

Ripeto, una affermazione detta così ("ogni oggetto ha il suo syncronization monitor") come quella sopra non ha molto valore. Di sicuro anche Python ne ha uno (evoluto o meno), mi viene difficile pensare che si appoggi direttamente alle "grossolane" primitive del s.o.

Grazie per tutta questa grande importanza che mi dai, ma è un po' difficile che proprio tu riesca a rompermi le scatole, visti anche i precedenti che abbiamo avuto in altre sezioni. :read: :D :Prrr: :cool:
Non me ne parlare... quanti post al vento... tu e fekinsieme avete la :muro: più dura del diamante:help: :oink: .

cdimauro
19-09-2008, 11:24
Ripeto, una affermazione detta così ("ogni oggetto ha il suo syncronization monitor") come quella sopra non ha molto valore.
E perché, scusa? Il "syncronization monitor" impegnerà delle risorse o sbaglio? Non è mica un'etichetta da appiccicare da qualche parte.
Di sicuro anche Python ne ha uno (evoluto o meno), mi viene difficile pensare che si appoggi direttamente alle "grossolane" primitive del s.o.
Queste cose le risolviamo con mutex et similia, e decidiamo noi quando usarli. ;)
Non me ne parlare... quanti post al vento... tu e fekinsieme avete la :muro: più dura del diamante:help: :oink: .
Peccato che io e Fran abbiamo sempre dimostrato di aver ragione. E voi di essere in torto. :D

Comunque acqua passata. Ormai vi abbiamo lasciato campo libero su news, articoli, Linux, ecc. ;) Dovreste esser contenti. :p

cionci
19-09-2008, 12:11
Basta frecciate fra voi. Grazie

Mazzulatore
19-09-2008, 13:00
E perché, scusa? Il "syncronization monitor" impegnerà delle risorse o sbaglio? Non è mica un'etichetta da appiccicare da qualche parte.Ti crea ambiguità la parola monitor? In questo caso particolare è una struttura dati per gestire la sincronizzazione. c'è in tutte le librerie e in tutti i runtime che supportano i threads. Ci sarà una differenza tra mutex e " id = semget(KEY, 1, 0600 | IPC_CREAT);" o sbaglio?
http://www.artima.com/insidejvm/ed2/threadsynch.html
Queste cose le risolviamo con mutex et similia, e decidiamo noi quando usarli. ;)

In java nessuno obbliga ad usare niente, mutex o syncronized sono equivalenti.

Peccato che io e Fran abbiamo sempre dimostrato di aver ragione. E voi di essere in torto. :D
Non se si parlano due lingue diverse.
Ora io dico che il significato di "syncronization monitor" è frainteso, tu fai intendere che in java ci sono dei difetti architetturali, cosa che se vera, vale per tutti i runtime/vm/interpreti.
Ma è sempre stato così.

Comunque acqua passata. Ormai vi abbiamo lasciato campo libero su news, articoli, Linux, ecc. ;) Dovreste esser contenti. :p
Non sono contento se mi dai del troll:mad:

cionci
19-09-2008, 13:04
Mazzulatore: ho detto basta

cdimauro
19-09-2008, 13:15
Ti crea ambiguità la parola monitor? In questo caso particolare è una struttura dati per gestire la sincronizzazione. c'è in tutte le librerie e in tutti i runtime che supportano i threads. Ci sarà una differenza tra mutex e " id = semget(KEY, 1, 0600 | IPC_CREAT);" o sbaglio?
http://www.artima.com/insidejvm/ed2/threadsynch.html

In java nessuno obbliga ad usare niente, mutex o syncronized sono equivalenti.

Non se si parlano due lingue diverse.
Ora io dico che il significato di "syncronization monitor" è frainteso, tu fai intendere che in java ci sono dei difetti architetturali, cosa che se vera, vale per tutti i runtime/vm/interpreti.
Ma è sempre stato così.
Nessuna ambiguità.

Il nocciolo della questione, se avessi letto tutta la discussione, era se Java impegnasse o meno delle risorse per OGNI oggetto che viene costruito.

E ovviamente da lì parte il confronto con altri linguaggi, come Python, che per OGNI oggetto NON alloca alcunché, delegando al programmatore il compito di utilizzare risorse come mutex, semafori, ecc. sotto il suo diretto controllo.

Spero sia chiaro adesso. ;)

Mazzulatore
19-09-2008, 16:24
Nessuna ambiguità.

Il nocciolo della questione, se avessi letto tutta la discussione, era se Java impegnasse o meno delle risorse per OGNI oggetto che viene costruito.

E ovviamente da lì parte il confronto con altri linguaggi, come Python, che per OGNI oggetto NON alloca alcunché, delegando al programmatore il compito di utilizzare risorse come mutex, semafori, ecc. sotto il suo diretto controllo.

Spero sia chiaro adesso. ;)

Da qui (http://www.javaworld.com/javaworld/jw-04-1996/jw-04-synch.html)
Every Java object instance and class potentially has a monitor associated with it. I say potentially because if you don't use any of the synchronization functions, the monitor is never actually allocated, but it's waiting there just in case.
si evince che in java non c'è effettiva allocazione di risorse per ogni oggetto. Il documento è un po' vecchio ma penso che sia cambiato poco alla fine e mi sembra, leggendo altre fonti che anche in .Net il discorso sia simile.

cdimauro
19-09-2008, 22:07
Non c'è allocazione per l'eventuale mutex, ma come puoi leggere c'è sempre un monitor allocato (parlo a livello di struttura dati) "just in case".

Quindi intanto alloco risorse, anche se non le userò mai. Come volevasi dimostrare. ;)

k0nt3
19-09-2008, 22:17
al contrario mi sembra di capire che il monitor viene allocato solo quando necessario

cdimauro
19-09-2008, 22:44
Il monitor inteso come risorse del s.o. (mutex, semafori, et similia) sì, ma la struttura che ospita il tutto è già presente in ogni oggetto a quanto pare. ;)

k0nt3
19-09-2008, 22:46
Il monitor inteso come risorse del s.o. (mutex, semafori, et similia) sì, ma la struttura che ospita il tutto è già presente in ogni oggetto a quanto pare. ;)

intendi la variabile che punta a null?

cdimauro
19-09-2008, 22:58
Non ne ho idea: non conosco i dettagli dell'implementazione.

cionci
20-09-2008, 08:38
Il monitor inteso come risorse del s.o. (mutex, semafori, et similia) sì, ma la struttura che ospita il tutto è già presente in ogni oggetto a quanto pare. ;)
Abbiamo problemi di memoria ? :D Poi tra l'altro, vista la VM quella struttura in runtime potrebbe anche occupare 0 byte di memoria ;)

cdimauro
20-09-2008, 10:41
Beh, Java li ha sicuramente: http://shootout.alioth.debian.org/gp4/benchmark.php?test=all&lang=javaclient&lang2=python :D

E' uno dei linguaggi / runtime più esosi in termini di memoria occupata.

Comunque non credo che la struttura per contenere il solo monitor (quindi senza allocare mutex & co.) occupi 0 byte: come minimo un puntatore messo a NULL nella struttura di ogni istanza ci sarà. ;)

k0nt3
20-09-2008, 11:18
problemi di memoria? pensa ai problemi di lentezza che ha python ;)
comunque è chiaro che non sappiamo come è implementata questa cosa, potrebbe occupare 0 byte come 4 byte in ogni caso non mi sembra sia grave.

cdimauro
20-09-2008, 11:24
problemi di memoria? pensa ai problemi di lentezza che ha python ;)
Mai negato questo.
comunque è chiaro che non sappiamo come è implementata questa cosa, potrebbe occupare 0 byte come 4 byte in ogni caso non mi sembra sia grave.
Da quel che si legge, almeno lo spazio per un puntatore (messo a NULL) per ogni oggetto dovrebbe starci.

marco.r
21-09-2008, 04:07
doppio...

marco.r
21-09-2008, 04:07
Giusto una cosa di python che mi da fastidio, ovvero come viene gestito lo scoping, in particolare in presenza di piu' scope locali (come puo' accadere in una closure)
Ad esempio a me viene naturale scrivere

def foo():
counter=0
def boo():
counter +=1
return counter
return boo

Ma non funziona perche' gli scope locali si annidano "male" e quello di boo e' diverso da quello di foo...
Il seguente invece funziona, ma non mi piace:

def foo():
counter=[0]
def boo():
counter[0] +=1
return counter[0]
return boo

pessima cosa...

Mazzulatore
22-09-2008, 11:21
Da quel che si legge, almeno lo spazio per un puntatore (messo a NULL) per ogni oggetto dovrebbe starci.

Questo è un suggerimento, non ho ancora idea di come sia effettivamente ma è un pattern ricorrente per tutti i tipi di risorse. Il Monitor dovrebbe occuparsi (o chi per lui) di riutilizzare semafori una volta allocati, dato che le system call di allocazione semaforo e memoria "costano cpu". Almeno spiegherebbe un riferimento a null una tantum "per object" al posto di uno nello stack "per mutex".

cdimauro
22-09-2008, 11:27
Giusto una cosa di python che mi da fastidio, ovvero come viene gestito lo scoping, in particolare in presenza di piu' scope locali (come puo' accadere in una closure)
Ad esempio a me viene naturale scrivere

def foo():
counter=0
def boo():
counter +=1
return counter
return boo

Ma non funziona perche' gli scope locali si annidano "male" e quello di boo e' diverso da quello di foo...
Il seguente invece funziona, ma non mi piace:

def foo():
counter=[0]
def boo():
counter[0] +=1
return counter[0]
return boo

pessima cosa...
Che è stata risolta con Python 3.0 con l'uso della keyword nonlocal se non error (concettualmente simile a global). :D

Aspetta un mesetto al più e sarai accontentato (Python 2.6, invece, arriva prima: il 1 ottobre). :)

mad_hhatter
22-09-2008, 13:05
class A(object):

def __init__(self, aSet = set()):

self.aMember = aSet

a = A()
b = A()
a.aMember.add('aValue')
print a is b, b.aMember


il risultato di questo pezzo di codice è:


False set(['aValue'])


mi pare di capire che python, nel caso in cui il valore di un parametro opzionale sia un oggetto mutable, causi un'interferenza tra le istanze provocata dal fatto che per ogni invocazione di A.__init__() aSet referenzia sempre lo stesso oggetto.

Non è un po' deleterio come comportamento?

cdimauro
22-09-2008, 14:50
Questo è un suggerimento, non ho ancora idea di come sia effettivamente ma è un pattern ricorrente per tutti i tipi di risorse. Il Monitor dovrebbe occuparsi (o chi per lui) di riutilizzare semafori una volta allocati, dato che le system call di allocazione semaforo e memoria "costano cpu". Almeno spiegherebbe un riferimento a null una tantum "per object" al posto di uno nello stack "per mutex".
Sì, la penso allo stesso modo.


class A(object):

def __init__(self, aSet = set()):

self.aMember = aSet

a = A()
b = A()
a.aMember.add('aValue')
print a is b, b.aMember


il risultato di questo pezzo di codice è:


False set(['aValue'])


mi pare di capire che python, nel caso in cui il valore di un parametro opzionale sia un oggetto mutable, causi un'interferenza tra le istanze provocata dal fatto che per ogni invocazione di A.__init__() aSet referenzia sempre lo stesso oggetto.

Non è un po' deleterio come comportamento?
Se lo confrontiamo con gli altri linguaggi di programmazione "classici", sicuramente.

Però ti faccio notare che prima hai creato DUE istanze di una classe e, a meno di far uso di factory che eseguono caching, singleton, o altro, saranno oggetti diversi. Quindi se chiedi a is b, per forza di cose ti verrà tornato False come risultato.

Tornando ai tipi mutabili, bisogna prestare attenzione se vengono messi come parametri opzionali. Questo perché il valore specificato verrà calcolato in fase di compilazione in bytecode della funzione e verrà passato a ogni invocazione della funzione. Questo vuol dire che il binding di aSet al valore set() verrà effettuato una sola volta, dopodiché riferendosi ad aSet ci si riferirà sempre allo stesso oggetto set(), creando quell'effetto di "condivisione" (non si tratta di un'interferenza) fra le varie chiamate.

La soluzione al problema è la seguente:

class A(object):

def __init__(self, aSet = None):

if aSet is None:
aSet = set()
self.aMember = aSet

a = A()
b = A()
a.aMember.add('aValue')
print a is b, b.aMember
che ritorna False set([])

Questo meccanismo viene spiegato nel tutorial e nel riferimento al linguaggio.

Non verrà sicuramente cambiato nemmeno in futuro, perché è basato sul dinamismo proprio del linguaggio. Infatti la definizione di una funzione in realtà comporta l'esecuzione del codice della definizione nel momento stesso in cui viene incontrata, e il risultato diventa il bytecode che verrà usato poi durante l'invocazione.
Questo è molto diverso dai linguaggi a compilazione statica, dove la funzione viene compilata prima ancora che il codice venga eseguito.

Per intenderci, in Python posso fare cose come questa:
if Debug:
def Log(self, *Args):
print datetime.datetime.now, ' '.join(Args)
else:
def Log(self, *Args):
pass
proprio perché il bytecode della funzione viene generato al momento preciso in cui si incontra l'istruzione def.

Comunque se non vi piace questo comportamento siete liberi di aggiungere la voce nella paginetta del wiki di cui è fatto oggetto questo thread. :)

Io ho mi sono limitato a spiegare la ratio che sta dietro a queste decisioni che a prima vista, abituati ai linguaggi tipicamente statici, possono risultare assurde / strane / controintuitive. ;)

mad_hhatter
22-09-2008, 15:14
Però ti faccio notare che prima hai creato DUE istanze di una classe e, a meno di far uso di factory che eseguono caching, singleton, o altro, saranno oggetti diversi. Quindi se chiedi a is b, per forza di cose ti verrà tornato False come risultato.


l'ho inserito solo per sottolineare che a e b non sono lo stesso oggetto, ma b prende il valore del membro di a.


Tornando ai tipi mutabili, bisogna prestare attenzione se vengono messi come parametri opzionali. Questo perché il valore specificato verrà calcolato in fase di compilazione in bytecode della funzione e verrà passato a ogni invocazione della funzione. Questo vuol dire che il binding di aSet al valore set() verrà effettuato una sola volta, dopodiché riferendosi ad aSet ci si riferirà sempre allo stesso oggetto set(), creando quell'effetto di "condivisione" (non si tratta di un'interferenza) fra le varie chiamate.

La soluzione al problema è la seguente:

class A(object):

def __init__(self, aSet = None):

if aSet is None:
aSet = set()
self.aMember = aSet

a = A()
b = A()
a.aMember.add('aValue')
print a is b, b.aMember
che ritorna False set([])

Questo meccanismo viene spiegato nel tutorial e nel riferimento al linguaggio.

Non verrà sicuramente cambiato nemmeno in futuro, perché è basato sul dinamismo proprio del linguaggio. Infatti la definizione di una funzione in realtà comporta l'esecuzione del codice della definizione nel momento stesso in cui viene incontrata, e il risultato diventa il bytecode che verrà usato poi durante l'invocazione.
Questo è molto diverso dai linguaggi a compilazione statica, dove la funzione viene compilata prima ancora che il codice venga eseguito.

Per intenderci, in Python posso fare cose come questa:
if Debug:
def Log(self, *Args):
print datetime.datetime.now, ' '.join(Args)
else:
def Log(self, *Args):
pass
proprio perché il bytecode della funzione viene generato al momento preciso in cui si incontra l'istruzione def.

Comunque se non vi piace questo comportamento siete liberi di aggiungere la voce nella paginetta del wiki di cui è fatto oggetto questo thread. :)

Io ho mi sono limitato a spiegare la ratio che sta dietro a queste decisioni che a prima vista, abituati ai linguaggi tipicamente statici, possono risultare assurde / strane / controintuitive. ;)

e io mi sono limitato a sollevare un problema, o meglio, a sottolineare un comportamento che può sembrare inaspettato a prima vista... il mio scopo non è certo sostenere che python faccia schifo: lo uso giornalmente con molta soddisfazione.

E' chiaro che dopo un attimo di riflessione il comportamento diventa condivisibile (il valore di default, di per sè stesso costante, è in questo caso una reference, con tutto ciò che questo comporta), ma all'inizio spiazza parecchio.

Ho continuato questo thread invece che aprirne uno nuovo perché qui si discutono aspetti controversi di alcuni linguaggi quindi mi pareva il luogo ideale e non mi pare che commentare una feature equivalga ad affermare la non adeguatezza di un linguaggio

cdimauro
22-09-2008, 15:22
D'accordissimo. Io mi sono limitato soltanto a sviscerare il problema. :)

Poi se qualcuno degli altri utenti ritiene che questo comportamento "sucks", è liberissimo di aggiungerlo a quella paginetta. ;)

gugoXX
15-10-2008, 17:33
Qualcuno ci ha visti...

http://www.appuntidigitali.it/2482/ne-ammazza-piu-la-lingua-che-la-spada/

Mi sa che e' bene che aggiunga qualcosina davvero.

71104
15-10-2008, 17:40
Ce n’è per tutti i gusti, anche se c’è chi s’è divertito a mettere assieme più “motivazioni” per PHP che per quasi tutti gli altri linguaggi messi assieme… :rotfl: :rotfl: :rotfl: :rotfl: :rotfl: :rotfl:


L’elenco dei linguaggi è variegato, ma si nota una macroscopica assenza: Perl. E’ stato fatto forse per non monopolizzare l’intero sito? deve fare proprio cagare questo Perl, tocca rimediare!! io non posso perché per mia fortuna non conosco quel linguaggio, ma mi sembra promettere peggio di PHP :asd:


Mi sa che e' bene che aggiunga qualcosina davvero. eddai su!! :D :D
ti ho pure dato lo start con la storia dei goto :asd:

cdimauro
15-10-2008, 20:57
Qualcuno ci ha visti...

http://www.appuntidigitali.it/2482/ne-ammazza-piu-la-lingua-che-la-spada/
:fiufiu:
deve fare proprio cagare questo Perl, tocca rimediare!! io non posso perché per mia fortuna non conosco quel linguaggio, ma mi sembra promettere peggio di PHP :asd:
Guarda tu stesso: http://perldoc.perl.org/perlintro.html E' una guida molto veloce.

Se poi vuoi farti del male, ma taaaaanto male, leggiti qualche guida alla programmazione "a oggetti" di Perl: http://perldoc.perl.org/perlboot.html :asd:

71104
15-10-2008, 21:28
Se poi vuoi farti del male, ma taaaaanto male, [...] e perché mai? ridere fa sempre bene :D