Ruby 2: some new things
-
Upload
david-black -
Category
Technology
-
view
463 -
download
0
description
Transcript of Ruby 2: some new things
Ruby 2some new things
David A. BlackLead DeveloperCyrus Innovation@david_a_black
Ruby Blind meetupApril 10, 2013
About me• Rubyist since 2000 (Pickaxe baby)
• Lead Developer, Cyrus Innovation
• Developer, author, trainer, speaker, event organizer
• Author of The Well-Grounded Rubyist
• Co-founder of Ruby Central
• Chief author of scanf.rb (standard library)
Today's topics• Lazy enumerators
• Module#prepend
• String#bytes and friends
• Keyword arguments
• Miscellaneous changes and new features
Lazy enumeratorsWhat's wrong with this code?
# find the first 10 multiples of 3
(0..Float::INFINITY).select {|x| x % 3 == 0 }.first(10)
Lazy enumerators
It runs forever!
# find the first 10 multiples of 3
(0..Float::INFINITY).select {|x| x % 3 == 0 }.first(10)
Lazy enumerators
# find the first 10 multiples of 3
(0..Float::INFINITY).lazy.select {|x| x % 3 == 0 }.first(10)
Lazy enumerators
# find the first 10 multiples of 3
(0..Float::INFINITY).lazy.select {|x| x % 3 == 0 }.first(10)
=> [0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
Lazy enumerators
r = 0..Float::INFINITYs = 0..Float::INFINITY
r.zip(s).first(5) # runs forever
Lazy enumerators
r = 0..Float::INFINITYs = 0..Float::INFINITY
r.lazy.zip(s).first(5)
=> [[0, 0], [1, 1], [2, 2], [3, 3], [4, 4]]
Lazy enumerators
# From Ruby source documentation
fib = Enumerator.new do |y| a = b = 1 loop do y << a a, b = b, a + b endend
fib.zip(0..Float::INFINITY).first(5) # runs forever
Lazy enumerators
fib = Enumerator.new do |y| a = b = 1 loop do y << a a, b = b, a + b endend.lazy
fib.zip(0..Float::INFINITY).first(5)
# => [[1, 0], [1, 1], [2, 2], [3, 3], [5, 4]]
Lazy enumerators• can be created via #lazy on an Enumerable
• [1,2,3].lazy
• (0..Float::INFINITY).lazy
• an_enumerator.lazy (see Fibonacci example)
Module#prependWhat will the output be?
class Person def talk puts "Hello" endend
module Yeller def talk super puts "I said... HELLLLLOOO!!!!" endend
class Person include Yellerend
david = Person.newdavid.talk
Module#prepend
class Person def talk puts "Hello" endend
module Yeller def talk super puts "I said... HELLLLLOOO!!!!" endend
class Person include Yellerend
david = Person.newdavid.talk
# => Hello
p Person.ancestors
# => [Person, Yeller, Object, Kernel, BasicObject]
Module#prependWhat will the output be?
class Person def talk puts "Hello" endend
module Yeller def talk super puts "I said... HELLLLLOOO!!!!" endend
class Person prepend Yellerend
david = Person.newdavid.talk
Module#prepend
class Person def talk puts "Hello" endend
module Yeller def talk super puts "I said... HELLLLLOOO!!!!" endend
class Person prepend Yellerend
david = Person.newdavid.talk
# => Hello I said... HELLLLLOOO!!!!
p Person.ancestors
# => [Yeller, Person, Object, Kernel, BasicObject]
Module#prepend• Puts the module *before* the receiver (class or module) in the method lookup path• A good way to avoid messing with alias
class Person def talk puts "Hello!" endend
class Person alias old_talk talk def talk old_talk puts "I said... HELLLLLOOO!!!!" endend
String#bytes/each_byte(and friends)
• String#bytes, #lines, #chars, #codepoints now return arrays
• #each_byte/line/char/codepoint still return enumerators
• Saves you having to do #to_a when you want an array
Keyword arguments
def my_method(a, b, c: 3) p a, b, cend
my_method(1, 2) # 1 2 3my_method(1, 2, c: 4) # 1 2 4
Lets you specify a default value for a parameter, and use the parameter's name in your method call
Keyword arguments
def my_method(a, b, *array, c: 3) p a, b, array, cend
my_method(1, 2, 3, 4, c: 5) # 1, 2, [3, 4], 5
Non-keyword arguments still work essentially the same way that they did.
Keyword arguments
def my_method(a, b, *array, c: 3, **others) p a, b, array, c, othersend
my_method(1, 2, 3, 4, c: 5, d: 6, e: 7) # 1, 2, [3, 4], 5, {:d=>6, :e=>7}
Extra keyword arguments get passed along in the **others parameter.
Keyword arguments
def my_method(a, b, c) p a, b, cend
my_method(1, 2, z: 3) # 1 2 {:z=>3}
Hash-like arguments that don't correspond to a named argument get passed along as a hash.
Keyword arguments
class Person attr_accessor :name, :email, :age
def initialize(name: "", email: "", age: 0) self.name = name self.email = email self.age = age endend
david = Person.new(email: "[email protected]", name: "David", age: Float::INFINITY)
Order doesn't matter:
Miscellaneous• %i{} and %I{}
• Default encoding now UTF-8 (no need for magic comment)
• Struct#to_h, nil#to_h, Hash#to_h
• Kernel#Hash (like Array, Integer, Float)
• const_get now parses nested constants
• Object.const_get("A::B::C")
• #inspect doesn't call #to_s any more
• Questions?
• Comments?
David A. BlackLead DeveloperCyrus Innovation@david_a_black
Ruby Blind meetupApril 10, 2013