Ruby 3.0.0 Preview 2 Dirilis

Kami dengan senang hati mengumumkan rilis dari Ruby 3.0.0-preview2.

Rilis ini mengenalkan sejumlah fitur baru dan perbaikan performa.

Analisis Statis

RBS

RBS adalah sebuah bahasa untuk mendeskripsikan tipe dari program Ruby.

Type checker termasuk TypeProf dan tool lainnya yang mendukung RBS akan memahami program Ruby jauh lebih baik dengan definisi RBS.

Anda dapat menuliskan definisi class dan module: method didefinisikan di dalam class, instance variables dan tipenya, serta hubungan inheritance/mix-in.

RBS memiliki tujuan untuk mendukung pola yang biasanya kita lihat dalam program Ruby dan memperbolehkan penulisan advanced types yang berisi union type, method overloading, dan generic. RBS juga mendukung duck typing dengan interface types.

Ruby 3.0 dirilis dengan gem rbs, yang memperbolehkan untuk mem-parse dan memproses definisi tipe yang ditulis di dalam RBS. Berikut ini adalah sebuah contoh kecil dari RBS dengan class, module, dan constant definition.

module ChatApp
  VERSION: String
  class Channel
    attr_reader name: String
    attr_reader messages: Array[Message]
    attr_reader users: Array[User | Bot]              # `|` means union types, `User` or `Bot`.
    def initialize: (String) -> void
    def post: (String, from: User | Bot) -> Message   # Method overloading is supported.
            | (File, from: User | Bot) -> Message
  end
end

Lihat README dari gem rbs untuk lebih detail.

TypeProf

TypeProf adalah sebuah type analysis tool yang di-bundle di dalam Ruby.

Saat ini, TypeProf berperan semacam sebuah type inference.

TypeProf membaca kode Ruby (non-type-annotated), menganalisis apa method yang didefinisikan dan bagaimana itu digunakan, dan menghasilkan sebuah prototipe dari type signature dalam format RBS.

Berikut adalah sebuah demonstrasi sederhana dari TypeProf.

Contoh masukan:

# test.rb
class User
  def initialize(name:, age:)
    @name, @age = name, age
  end
  attr_reader :name, :age
end
User.new(name: "John", age: 20)

Contoh keluaran:

$ typeprof test.rb
# Classes
class User
  attr_reader name : String
  attr_reader age : Integer
  def initialize : (name: String, age: Integer) -> [String, Integer]
end

Anda dapat menjalankan TypeProf dengan menyimpan masukan sebagai “test.rb” dan memanggilnya dengan perintah “typeprof test.rb”.

Anda juga dapat mencoba TypeProf daring. (Ini menjalankan TypeProf di server, maaf jika hasilnya tidak keluar)

Lihat dokumentasi dan demonstrasi untuk detail.

TypeProf masih eksperimental dan belum sempurna; hanya sebagian dari bahasa Ruby didukung dan pendeteksian type error terbatas. Tetapi, ini masih bisa berkembang dengan memperbaiki cakupan dari fitur bahasa, performa analisis, dan kegunaan. Masukan apapun sangat diterima.

Ractor (eksperimental)

Ractor adalah sebuah Actor-model seperti concurrent abstraction yang didesain untuk menyediakan sebuah fitur eksekusi paralel tanpa mengkhawatirkan thread-safety.

Anda dapat membuat beberapa ractor dan menjalankannya secara paralel. Ractor memungkinkan untuk membuat program paralel yang thread-safe karena ractor tidak dapat membagi objek normal. Komunikasi antar ractor didukung oleh message passing.

Untuk membatasi pembagian objek, Ractor mengenalkan beberapa batasan pada sintaks Ruby (tanpa banyak Ractor, maka tidak ada batasan).

Spesifikasi dan implementasi dari Ractor masih belum sempurna dan memungkinkan adanya perubahan ke depan, sehingga fitur ini ditandai dengan eksperimental dan menampilkan peringatan “experimental feature” saat Ractor.new pertama kali.

Berikut adalah program kecil yang mengecek n.prime? (n adalah relatif sebuah big integer) secara paralel dengan dua ractor. Anda bisa memastikan jika program akan memiliki kecepatan 2 kali lebih cepat dibanding program sequential pada komputer paralel.

require 'prime'
# n.prime? dengan integer r1, r2 jalan secara paralel
r1, r2 = *(1..2).map do
  Ractor.new do
    n = Ractor.recv
    n.prime?
  end
end
# parameter dikirim
r1.send 2**61 - 1
r2.send 2**61 + 15
# menunggu hasil dari expr1, expr2
p r1.take #=> true
p r2.take #=> true

Lihat doc/ractor.md untuk lebih detail.

Fiber Scheduler

Fiber#scheduler diperkenalkan untuk menghalangi operasi blocking. Ini memperbolehkan light-weight concurrency tanpa pengubahan kode yang sudah ada. Tonton “Don’t Wait For Me, Scalable Concurrency for Ruby 3” sebagai gambaran bagaimana fitur ini bekerja.

Saat ini, class/method yang didukung:

  • Mutex#lock, Mutex#unlock, Mutex#sleep
  • ConditionVariable#wait
  • Queue#pop, SizedQueue#push
  • Thread#join
  • Kernel#sleep
  • Process.wait
  • IO#wait, IO#read, IO#write dan method yang berkaitan (seperti #wait_readable, #gets, #puts dan lainnya).
  • IO#select tidak didukung. (Jelaskan gem Async dengan tautan). Ini adalah contoh program yang akan melakukan request HTTP secara bersamaan: (Jelaskan ini:)
    1. async adalah gem dari luar
    2. async menggunakan fitur baru ini
require 'async'
require 'net/http'
require 'uri'
Async do
  ["ruby", "python", "c"].each do |topic|
    Async do
      Net::HTTP.get(URI "https://www.google.com/search?q=#{topic}")
    end
  end
end

Fitur Baru Lainnya

  • One-line pattern matching sekarang menggunakan => daripada in.
      # version 3.0
      {a: 0, b: 1} => {a:}
      p a # => 0
      # version 2.7
      {a: 0, b: 1} in {a:}
      p a # => 0
    
  • Find pattern ditambahkan.
      case ["a", 1, "b", "c", 2, "d", "e", "f", 3]
      in [*pre, String => x, String => y, *post]
        p pre  #=> ["a", 1]
        p x    #=> "b"
        p y    #=> "c"
        p post #=> [2, "d", "e", "f", 3]
      end
    
  • Definisi endless method ditambahkan.
      def square(x) = x * x
    
  • Hash#except sekarang built-in.
      h = { a: 1, b: 2, c: 3 }
      p h.except(:a) #=> {:b=>2, :c=>3}
    
  • Memory view ditambahkan sebagai sebuah fitur eksperimental
    • Ini adalah sebuah kumpulan C-API baru yang menukar sebuah area raw memory, seperti sebuah numeric array dan sebuah bitmap image, antara pustaka extension. Pustaka extension dapat juga membagikan metadata dari area memory yang terdiri dari bentuk, format elemen, dan sebagainya. Menggunakan semacam metadata seperti ini, pustaka extension bahkan dapat membagikan sebuah multidimensional array dengan tepat. Fitur ini didesain dengan merujuk pada buffer protocol dari Python.

Perbaikan performa

  • Banyak perbaikan yang telah diimplementasikan dalam MJIT. Lihat NEWS untuk detail.
  • Menempelkan kode yang panjang pada IRB 53 kali lebih cepat dibandingkan yang di-bundle dengan Ruby 2.7.0. Sebagai contoh, waktu yang dibutuhkan untuk menempelkan kode ini berubah dari 11.7 detik menjadi 0.22 detik.

Perubahan penting lainnya sejak 2.7

  • Keyword argument dipisahkan dari argument lainnya.
    • Pada dasarnya, kode yang mencetak sebuah peringatan pada Ruby 2.7 tidak akan bekerja. Lihat dokumen untuk detail.
    • Omong-omong, argument forwarding sekarang mendukung leading argument.
      def method_missing(meth, ...)
        send(:"do_#{ meth }", ...)
      end
      
  • Fitur $SAFE telah dihilangkan; sekarang adalah sebuah variabel global.
  • Urutan dari backtrace telah dibalik pada Ruby 2.5, tetapi itu dibatalkan. Sekarang urutan berperilaku seperti Ruby 2.4; pesan error dan nomor baris di mana exception terjadi dicetak terlebih dahulu dan pemanggilnya baru dicetak kemudian.
  • Beberapa pustaka standar yang diperbarui.
    • RubyGems 3.2.0.rc.1
    • Bundler 2.2.0.rc.1
    • IRB 1.2.6
    • Reline 0.1.5
  • Berikut adalah pustaka yang tidak lagi masuk sebagai bundled gem. Pasang gem berikut jika ingin menggunakan fiturnya.
    • net-telnet
    • xmlrpc
  • Berikut adalah default gem yang sekarang menjadi bundled gem.
    • rexml
    • rss
  • Berikut adalah berkas stdlib yang sekarang menjadi default gem dan telah dipublikasikan ke rubygems.org
    • abbrev
    • base64
    • English
    • erb
    • find
    • io-nonblock
    • io-wait
    • net-ftp
    • net-http
    • net-imap
    • net-protocol
    • nkf
    • open-uri
    • optparse
    • resolv
    • resolv-replace
    • rinda
    • securerandom
    • set
    • shellwords
    • tempfile
    • time
    • tmpdir
    • tsort
    • weakref

Lihat NEWS atau commit logs untuk lebih detail.

Dengan perubahan tersebut, 3776 berkas berubah, 181573 sisipan(+), 145096 terhapus(-) sejak Ruby 2.7.0!

Mohon coba Ruby 3.0.0-preview2 dan berikan kami masukan!

Unduh

  • https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0-preview2.tar.gz

    SIZE: 19378626
    SHA1: 25363b20225850224e7835e99906c52f2ff57792
    SHA256: 9de8661565c2b1007d91a580e9a7e02d23f1e8fc8df371feb15a2727aa05fd9a
    SHA512: 6fa4191425ae71e41894b60bd9c31d483a562ee8216886360ce18238ab48115b95be0367708612c45f634e7584fba8940a524ba0113ce0f36ce4df78a112d0b7
    
  • https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0-preview2.tar.xz

    SIZE: 14244252
    SHA1: 54e4d3892ce480106382bd2d36dd7395e01b0f2a
    SHA256: 03078e82d4fb55c13837c69e56565fc49c451d11b1ca5e1b075d990d0957f181
    SHA512: 8b0e6e3ba7e5f95586b4438d965e7b09187ad599f4ac22dec3db7b176358514fe0c0890dde8912fef1ef92ffcde3f6f1228178eabadcf3a05601e5b6f05881ae
    
  • https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0-preview2.zip

    SIZE: 23907144
    SHA1: 064ee265c94b3df87e737622ba84437ea0d6aeaf
    SHA256: 19e295ae50934ddac2b366f0c7c8de9bd710d596b76eba02152f3641e5ce2b23
    SHA512: 598def50ef9e8ae1f44e05ff2c4e35acf252437286f08644ba5e301ebff2db399140bafa72868877100d6ffa736a4474cb7b99ecea8bdf835ed113ab250bb3d9
    

Apa itu Ruby

Ruby pertama kali dikembangkan oleh Matz (Yukihiro Matsumoto) pada 1993 dan sekarang dikembangkan sebagai Open Source. Ruby berjalan di berbagai jenis platform dan digunakan di seluruh dunia khususnya pengembangan web.