Ł ukasz Adamczak http://czak.pl Co nowego w ś wiecie Ruby ’ ego
Na czym stoimy?
Luty 1993Matz zaczyna pracę nad Rubym
Grudzień 1996Ruby 1.0
Grudzień 2001“Programming Ruby”
Lipiec 2004Ruby on Rails
Zdjęcia: Marcin Bajer, Roo Reynolds
Marzec 2007Ruby 1.8.6
Tu jesteś
Grudzień 2007Ruby 1.9.0
Maj 2008Ruby 1.8.7
Koniec 2008 (?)Ruby 2.0
Quo vadis, Ruby?
6Wydajność
UnicodeKolekcje
Lambdy i ProceFibersPerełki
Wydajność
Stan na dziś
Źródło: Ruby vs PHP Performance Revisited
YARV na ratunek
• Autor - Koichi Sasada
• “Yet Another Ruby VM”
• Merge - styczeń 2007
• Standard od 1.9
Zdjęcie: Marcin Bajer
Efekt?
Źródło: The Great Ruby Shootout
Inne implementacje
Źródło: The Great Ruby Shootout
Unicode
Gżegżółka?
こんにちは
كيف حالك؟ • Wiele standardów kodowania
• String - ciąg znaków, nie bajtów
• Klasa Encoding• String < Enumerable• Rozbudowa API
Przykład
Ruby 1.8
> "Łukasz".length=> 7
> "Łukasz".reverse=> "zsaku\201\305"
> "Łukasz"[0]=> 197
Ruby 1.9
> "Łukasz".length=> 6
> "Łukasz".reverse=> "zsakuŁ"
> "Łukasz"[0]=> "Ł"
NEW!
Przykład c.d.
Ruby 1.8
> "Łukasz"[0]=> 197
Ruby 1.9
> "Łukasz"[0]=> "Ł"
NEW!
> ?u=> 117
> "pies"[1]=> 105
> ?u=> "u"
> "małpa"[2]=> "ł"
Encoding
んにちは
• Odwzorowaniebajty ↔ znaki
• Atrybut każdego Stringa
• Standardowe:ASCII_8BIT, UTF_8,EUC_JP, SHIFT_JIS
• Narzucenie, konwersja kodowania
0101101
Przykład c.d.
Ruby 1.9
# coding: utf-8
# w pliku źródłowym:"Łukasz".encoding # => <Encoding: UTF-8>"Lukasz".encoding # => <Encoding: ASCII-8BIT>
# z zewnętrznego źródła:text = stream.readline.force_encoding("utf-8")f = File.open("data.txt", "r:utf-8")
# konwersja:euro = "€"euroiso = euro.encode("iso-8859-15")
Kolekcje
Enumerator• Klasa Enumerable::Enumerator
• Proxy dla kolekcji
• Kolekcje z “byle czego”
• Automatyczna konstrukcja
• Zewnętrzne iteratory
Przykład# zwykłe proxyenum = [1, 2, 3].to_enum
# konkretny iteratorenum = "hello".enum_for(:each_byte) :each_char :each_line
# automatycznie (tylko 1.9)enum = "hello".each_char # => Enumerable::Enumeratorenum = "hello".charsenum = 1.upto(10)
# mniam"hello".chars.map {|c| c.succ}.join # => "ifmmp"
Ruby 1.9
Przykład c.d.# zewnętrzny iteratoriter = "hello".charsbegin puts iter.next while truerescue StopIteration puts "koniec"end
# "przewinięcie" iteratoraiter.rewind
# Kernel.loop przechwytuje StopIterationloop do puts iter.nextendputs "i znowu koniec"
Ruby 1.9
Lambdy i Proce
Lambdy i Proce• MetodyKernel.proc, Kernel.lambda
• Lambda literals
• Domyślne wartości parametrów
• Uproszczone wywołanie
• lambda?
Tworzenie proc / lambda
# tworzenie procyp = Proc.new { … }
# tworzenie lambdyl = lambda { … }
p = proc { … }
Ruby 1.9Ruby 1.8
# tworzenie procyp = Proc.new { … }
# tworzenie lambdyl = lambda { … }l = proc { … }
NEW!
Lambda literals
Ruby 1.9
# dotychczassquare = lambda { |x| x**2 }
# nowośćsquare = ->(x){ x**2 }
# domyślne parametrypow = ->(x, exp=2){ x**exp }
# można też tak:pow = -> x, exp=2 { x**exp }
Wywoływanie
Ruby 1.9
square = ->(x){ x**2 }
# można tak:square.call(14)
# albo tak:square[14]
# a teraz dodatkowo tak:square.(14)
Włókna
Fiber
• Co-routines (współprogramy)
• Tworzenie generatorów
• Konwersja zewnętrzne -- wewnętrzne iteratory
Przykład# generator ciągu Fibonacciego:f = Fiber.new do x, y = 0, 1 loop do Fiber.yield y x, y = y, x+y endend
Ruby 1.9
# użycie:10.times { puts f.resume }
Przykład
Ruby 1.9
# wymiana danych między włóknem a głównym wątkiemf = Fiber.new do |message| puts "Program mówi: #{message}" message2 = Fiber.yield "No witam!" puts "Program mówi: #{message2}" "Pozdro"end
# wykonanie:response = f.resume("Cześć")puts "A włókno na to: #{response}"response2 = f.resume("Muszę lecieć")puts "A włókno na to: #{response}"
Przykład c.d.class Generator def initialize(enumerable) @enumerable = enumerable @fiber = Fiber.new do @enumerable.each do |i| Fiber.yield i end raise StopIteration end end def next @fiber.resume endend
Ruby 1.9
# użycie:g = Generator.new([1, 3, 5])loop { puts g.next }
Perełki
{ name: "Anna", age: 27 }
Nowa składnia Hashy
arr.each do |i;x,y| # …end
Zmienne lokalne dla bloku
def foo(x, y=10, z) "#{x}, #{y}, #{z}"end
foo(1, 2) # => "1, 10, 2"
Domyślne wartości parametrów.succ
[1, 2, 3].reduce(:+)
reduce
"hello".each_char.with_index {|c,i| … }
a = [1, 2, 3]a.permutation(2)a.combination(2)
with_index
Permutacje i kombinacje
"hello".chomp.tap {|s| p s}.reverse
tap
Pytania?