12

Sono passati 22 anni tra l'uscita pubblica iniziale di Perl 1.0 (18 dicembre 1987) e l'attuale versione stabile 5.10.1 (2009).Quali sono alcuni esempi specifici di incompatibilità con le versioni precedenti di Perl?

Durante questi 22 anni le seguenti versioni notevoli sono stati fatti:

  • Perl 1.0 (1987 - prima release)
  • Perl 2 (1988 - migliori espressioni regolari)
  • Perl 3 (1989 - supporto per i flussi di dati binari)
  • Perl 4 (1991 - identificazione della versione di Perl descritta nel Libro di cammello)
  • Perl 5 (1994 - modifiche principali introdotte, quasi completa riscrittura dell'interprete)
  • Perl 5.6 (2000-64 supporto bit, stringhe Unicode, supporto per file di grandi dimensioni)
  • Perl 5.8 (2002 - migliorato il supporto unicode, nuova implementazione IO)
  • Perl 5.10 (2007 - nuova istruzione switch, aggiornamenti espressioni regolari , operatore smart match)

Sto cercando esempi specifici di incompatibilità all'indietro nella storia di Perl.

Domanda:

  • In 22 anni di storia del Perl, ci sono esempi di Perl indietro incompatibilità quando Perl codice sorgente mira Perl versione X non verrà eseguito in versione Y (dove Y> X) ?

Si prega di includere riferimenti ed esempi di codice quando possibile.

risposta

14

Una delle maggiori incompatibilità intenzionali è l'interpolazione degli array che è cambiata tra Perl 4 e Perl 5.

my @example = qw(1 2 3); 
print "[email protected]"; 

In Perl 4, che sarebbe:

[email protected] 

In Perl 5 che sarebbe:

foo1 2 3.com 

Fortunatamente, se la matrice non esiste Perl vi avvertirà " possibile interpolazione involontaria ".

I thread hanno subito un grande cambiamento tra 5.005 e 5.6. "5005 thread" utilizzava il modello di threading POSIX tradizionale in cui tutti i dati globali sono condivisi. Mentre in teoria questo era più veloce, perché allora il Perl poteva usare solo i thread POSIX, era un incubo per i programmatori Perl. La maggior parte dei moduli Perl non erano thread-safe. E non ha mai funzionato davvero bene.

In 5.6, ActiveState e altri hanno fatto fork() su Windows. Quando fork() su Windows, Perl crea una copia dell'oggetto interprete ed esegue gli opcode di entrambi gli interpreti. Questo era noto come "molteplicità".

In 5.8, Arthur Bergman ha funzionato con quello e lo ha usato per creare ithreads. Poiché la molteplicità sta emulando un processo separato, nessun dato è condiviso per impostazione predefinita. Solo i dati che dici è condiviso è condiviso. Questo li rende molto più sicuri da usare, anche se ci è voluto molto tempo prima che gli ithreads fossero stabili. Gente come Elizabeth Mattijsen e Jerry Hedden hanno fatto in modo che accadesse.

5005threads sono stati finalmente cancellati in 5.10.0. Esiste un livello di compatibilità, ma dubito che funzionerebbe davvero nel codice di produzione.

Un'altra grande incompatibilità si è avuta con Unicode tra 5.6 e 5.8. Unicode in 5.6 soffiava. Indipendentemente dal fatto che una stringa fosse Unicode è stato deciso dall'ambito circostante. È stato completamente riprogettato in 5.8, quindi ora l'Unicodeiness di una stringa è legato alla stringa. Il codice scritto usando l'Unicode di 5.6 di solito doveva essere riscritto in 5.8, spesso perché per ottenere l'Unicode 5.6 di funzionare correttamente bisognava fare brutti hack.

Recentemente 5.10.1 ha apportato una serie di modifiche incompatibili a smart-match. Fortunatamente sono stati introdotti in 5.10.0 quindi non è un grosso problema. La storia di Perl 6 ha introdotto il concetto di smart-match, ed è stato sostituito con una versione di sviluppo di Perl 5. Il tempo è passato, e l'idea di Perl 6 di smart-matching è cambiata. Nessuno ha detto ai ragazzi di Perl 5 ed è uscito in 5.10.0 invariato. Larry Wall noticed and did the equivalent of OMG YER DOIN IT WRONG!!! La nuova versione di Perl 6 è stata vista come decisamente migliore e quindi 5.10.1 l'ha risolto.

12

Pseudo-hashes sono un recente esempio che mi viene in mente. In generale, perldelta files ha una panoramica delle modifiche incompatibili in una versione specifica. Questi cambiamenti sono quasi sempre o oscuri (come pseudo-hash) o piccoli.

+0

Mi hai battuto. Stavo per dichiarare gli pseudo-hash. :-) –

+0

È solo piccolo se riesci a insegnare a tutti gli sviluppatori della tua azienda a non fare riferimento a campi pseudohash come '$ this -> [$ this -> [0] -> {fieldname}]'. Sigh ... – Ether

+6

Gli pseudo-hash sono sempre stati etichettati come un esperimento. Non è colpa mia se li hai usati nel codice di produzione. : P – Schwern

11

Sì. Ce ne sono molti, anche se di solito sono minori. A volte ciò è dovuto ai cicli di deprecazione che terminano alla fine nella rimozione. A volte è dovuto al cambiamento della semantica per nuove funzionalità (e sperimentali). A volte si tratta di correzioni di bug per cose che non funzionavano correttamente. Gli sviluppatori di Perl si impegnano molto a preservare la retrocompatibilità tra le versioni laddove possibile. Non ricordo di aver mai avuto uno script che è stato rotto aggiornando ad una nuova versione di Perl.

L'ordine hash interno è stato modificato più volte. Anche se questo non è qualcosa su cui devi fare affidamento, può causare problemi se lo fai involontariamente.

L'incompatibilità binaria tra le versioni principali (5.x) è comune, ma in genere significa che è necessario ricompilare eventuali estensioni XS.

L'elenco completo è troppo lungo per essere elencato qui. Puoi ottenerlo selezionando la sezione "Modifiche incompatibili" di ogni versione di history.

+0

L'ordine di hash interno è randomizzato nelle versioni più recenti. –

+0

@ Brad Gilbert: Sì e no. La randomizzazione hash è stata aggiunta in 5.8.1 ma a 5.8.2 si verifica solo se la distribuzione delle chiavi è scarsa. –

5

OTOH ci sono alcune caratteristiche selvagge risalenti a Perl 1 che funzionano ancora. Ad esempio, che cosa stampa?

%foo = (foo => 23); 
print values foo 

Proprio così, 23. Perché? Perché "array associativi" non erano oggetti di prima classe in Perl 1. $foo{bar} funzionava ma non c'era %foo. Non so davvero perché, anche la pagina man Perl 1 riconosce che questo è verrucoso. Quindi, per la compatibilità con Perl 1 è possibile accedere a un hash globale senza usare uno %, forse se la tastiera è rotta o Apple decide che nessuno usa il simbolo %.

chdir ha alcune stranezze. chdir() senza argomenti ti porterà alla tua home directory, replicando il comportamento della shell cd. Sfortunatamente lo sarà anche chdir undef e chdir "" rendendo difficile il rilevamento degli errori intorno a chdir. Fortunatamente questo comportamento è deprecato. Dovrò assicurarmi che muoia in 5.14.

$[ è ancora in circolazione e rimane non approvato, ma "altamente scoraggiato". Cambia ciò che il primo indice di un array è, quindi se sei un essere umano come me e contare da 1 si poteva fare:

$[ = 1; 
@foo = qw(foo bar baz); 
print $foo[2]; # prints bar 

Perl 5 ha cambiato per essere il file con ambito, come il resto è stato un resistenza alle prestazioni e una grande fonte di CrAZY.

+2

* Hash% foo manca% in argomento ... * Questo è un avviso che non ho mai visto prima. Mi piace la descrizione di perldiag: "Perl molto vecchio ti consente di omettere la% dei nomi di hash in alcuni punti, che ora è pesantemente deprecato." Apparentemente non è deprecato abbastanza pesantemente da rimuoverlo, comunque. –

3

Ho avuto alcuni errori funky con Perl4 e Perl5 valutare la mano sui lati sinistro e destro di un incarico in un ordine diverso, citando le Perl traps for the unwary:

LHS RHS contro di qualsiasi operatore di assegnazione. LHS viene valutato prima in perl4, secondo in perl5; questo può influenzare la relazione tra effetti collaterali nelle sottoespressioni.

@arr = ('left', 'right'); 
$a{shift @arr} = shift @arr; 
print join(' ', keys %a); 
# perl4 prints: left 
# perl5 prints: right 

per alcune cose nuove e, eventualmente incompatibili, vedi the FAQ tra Perl4 e Perl5.

Problemi correlati