Co nowego w świecie Ruby\'ego

Post on 28-Nov-2014

3.577 views 3 download

description

 

Transcript of Co nowego w świecie Ruby\'ego

Łukasz Adamczakhttp://czak.pl

Co nowegow ś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ść

YARV na ratunek

• Autor - Koichi Sasada

• “Yet Another Ruby VM”

• Merge - styczeń 2007

• Standard od 1.9

Zdjęcie: Marcin Bajer

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?

Dziękuję© 2008 Łukasz Adamczak