È stata rilasciata Ruby 3.4.0, un linguaggio di programmazione orientato agli oggetti e dinamico, concepito per l'elevata efficacia nello sviluppo di software e che incorpora le migliori caratteristiche di Perl, Java, Python, Smalltalk, Eiffel, Ada e Lisp. Il codice del progetto è distribuito sotto le licenze BSD («2-clause BSDL») e «Ruby», quest'ultima fa riferimento all'ultima versione della licenza GPL ed è compatibile con GPLv3.
Miglioramenti principali:
- È stato aggiunto un nuovo identificatore «it», che rappresenta un parametro non nominato passato nel blocco predefinito. Il nuovo identificatore è simile alla variabile «_1» precedentemente disponibile quando si passa un solo parametro a un blocco. L'introduzione di questo nuovo identificatore è motivata dal desiderio di eliminare la confusione causata dalla possibilità di passare più parametri a un blocco («it» implica che c'è sempre solo un argomento, mentre con «_1» non è chiaro se esista un parametro «_2»). [1, 2, 3].each { puts _1 } [1, 2, 3].each { puts it } ary = [«foo», «bar», «baz»] p ary.map { it.upcase } #=> [«FOO», «BAR», «BAZ»]
- Di default è attivato il parser Prism, che è più portabile, facile da mantenere e consente di gestire gli errori nel codice. Per analizzare il codice in Ruby, sono disponibili i metodi Prism.parse(source) per ottenere la rappresentazione AST del codice, Prism.parse_comments(source) per estrarre i commenti dal codice e Prism.parse_success?(source) per verificare la presenza di errori nel codice. Per tornare al parser precedente "parse.y", è possibile utilizzare l'opzione "—parser=parse.y".
- Nella libreria «socket» è stata implementata e abilitata per impostazione predefinita il supporto per l'algoritmo Happy Eyeballs (RFC 8305) per la scelta del protocollo ottimale quando ci si connette a host disponibili tramite indirizzi IPv4 e IPv6. Utilizzando l'algoritmo Happy Eyeballs, il client risolve subito gli indirizzi IPv4 e IPv6 per l'host e invia una richiesta di connessione tramite IPv6, quindi, dopo un ritardo di 250 ms, tenta di connettersi in parallelo agli altri indirizzi associati all'host, senza attendere il risultato dei tentativi di connessione precedenti. Rimane attiva la connessione stabilita per prima, mentre le altre vengono chiuse. In precedenza, la chiamata ai metodi TCPSocket.new e Socket.tcp nei programmi Ruby comportava tentativi di risoluzione sequenziali degli indirizzi IPv4/IPv6 e di connessione, portando a ritardi, ad esempio, quando il primo tentativo di connessione era stato effettuato tramite IPv6, ma il sistema non supportava IPv6. Per ripristinare il vecchio comportamento, è possibile utilizzare la variabile d'ambiente «RUBY_TCP_NO_FAST_FALLBACK=1», la configurazione «Socket.tcp_fast_fallback=false» o l'argomento «fast_fallback: false» quando si chiamano i metodi.
- È proseguita l'ottimizzazione delle prestazioni del compilatore JIT YJIT, sviluppato dai creatori della piattaforma di e-commerce Shopify nell'ambito di un'iniziativa per migliorare le prestazioni delle applicazioni Ruby che utilizzano il framework Rails e che fanno un uso intensivo di metodi. A differenza del compilatore JIT MJIT, il nuovo YJIT applica la versioning dei blocchi di base (LBBV - Lazy Basic Block Versioning) invece di trattare i metodi nella loro interezza ed è implementato come un compilatore JIT integrato, scritto in Rust. Grazie a LBBV, il JIT compila inizialmente solo l'inizio del metodo e il resto viene compilato successivamente, dopo che sono stati determinati i tipi delle variabili e degli argomenti utilizzati durante l'esecuzione.
Nella nuova versione, nella maggior parte dei test su sistemi x86_64 e ARM64, è stato possibile ottenere un miglioramento delle prestazioni di YJIT. Sono state aggiunte nuove ottimizzazioni: utilizzo di registri per le variabili locali e gli argomenti dei metodi; impiego delle implementazioni Ruby di Array#each, Array#select e Array#map; espansione inline di metodi vuoti e metodi che restituiscono costanti, l'istanza stessa o l'argomento di ingresso; generatori di codice separati per determinati metodi; ottimizzazione della gestione delle stringhe (String#getbyte, String#setbyte); accelerazione delle operazioni bitwise.
Ridotto il consumo di memoria grazie alla compressione dei metadati e all'implementazione di un sistema unificato di limitazioni. È stata aggiunta l'opzione "—yjit-mem-size", impostata per default a 128MiB, che influisce sul consumo complessivo di memoria. È stata aggiunta l'opzione "—yjit-log" per attivare il tracciamento del codice compilato.
- È stata fornita la possibilità di caricare dinamicamente collezionatori di spazzatura alternativi, raccolti in forma di librerie condivise. Per specificare la libreria con il collezionista di spazzatura desiderato, è necessario utilizzare la variabile d'ambiente RUBY_GC_LIBRARY. Il collezionista di spazzatura incorporato, attivato per impostazione predefinita, può ora essere compilato come libreria separata. Inoltre, è stato aggiunto un collezionista di spazzatura basato sul framework MMTk, scritto nel linguaggio Rust.
- È consentito passare a metodi argomenti denominati che hanno valore nil. Gli argomenti con valore «**nil» vengono ora trattati come un hash vuoto «**{}» senza passare argomenti denominati al metodo.
- È vietato passare blocchi e specificare argomenti denominati negli indici, ad esempio, «a[&b]=c» e «o[1, a: 1]».
- Ottimizzato il metodo JSON.parse, che ora funziona una volta e mezzo più veloce del pacchetto json 2.7.
Fonte: opennet.ru
