Skip to content

Instantly share code, notes, and snippets.

@matsadler
Created November 2, 2012 14:13
Show Gist options
  • Save matsadler/4001581 to your computer and use it in GitHub Desktop.
Save matsadler/4001581 to your computer and use it in GitHub Desktop.
A few examples of the ruby 2.0.0 preview 1 highlights given in http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/46348
# Ruby 2.0.0 preview 1 highlights
# A few examples of the highlights given in
# http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/46348
# Refinements
# ===========
# create a namespaced refinement
module NumberQuery
refine String do
def number?
match(/^[1-9][0-9]+$/) ? true : false
end
end
end
# it's not available outside that namespace
begin
"123".number?
rescue => e
p e #=> #<NoMethodError: undefined method `number?' for "123":String>
end
# it is inside!
module NumberQuery
p "123".number? #=> true
end
# or you can add it to another namespace like so
module MyApp
using NumberQuery
p "123".number? #=> true
p "foo".number? #=> false
end
# Keyword arguments
# =================
def wrap(string, before: "<", after: ">")
"#{before}#{string}#{after}" # no need to retrieve options from a hash
end
# optional
p wrap("foo") #=> "<foo>"
# one or the other
p wrap("foo", before: "#<") #=> "#<foo>"
p wrap("foo", after: "]") #=> "<foo]"
# order not important
p wrap("foo", after: "]", before: "[") #=> "[foo]"
# double splat to capture all keyword arguments, or use as hash as keyword
# arguments
def capture(**opts)
opts
end
p capture(foo: "bar") #=> {:foo=>"bar"}
# keys must be symbols
opts = {:before => "(", :after => ")"}
p wrap("foo", **opts) #=> "(foo)"
# the old hash style syntax is still accepted for keyword arguments
p wrap("foo", :before => "{", :after => "}") #=> "{foo}"
# Enumerator#lazy
# ===============
# making an enumerable lazy makes it possible to enumerate infinite collections
require "timeout"
begin
timeout(1) {[1,2,3].cycle.map {|x| x * 10}}
rescue => e
p e #=> #<Timeout::Error: execution expired>
end
p [1,2,3].lazy.cycle.map {|x| x * 10}.take(5).to_a #=> [10, 20, 30, 10, 20]
# a lazy enumerable will evaluate the entire chain for each element at a time,
# rather than all elements at each stage of the chain, so the following will
# output at 1 second intervals. Without #lazy all output would come after 3
# seconds
class Foo
include Enumerable
def each
sleep 1
yield 1
sleep 1
yield 2
sleep 1
yield 3
end
end
Foo.new.lazy.map {|x| x * 10}.each {|x| p x}
# you would think that as the collection is only iterated once #lazy might
# speed things up, unfortunately this generally isn't the case
# Module#prepend
# ==============
module A
def foo
"A"
end
end
# regular module include, the method in the class overrides the module
# (module method is available as `super`)
class B
include A
def foo
"B"
end
end
p B.new.foo #=> "B"
# with prepend the module method overides that in the class
# (in the case the method in the class is available as super)
class C
prepend A
def foo
"B"
end
end
p C.new.foo #=> "A"
# Converting convention to Hash: #to_h
# ====================================
p({:foo => 1}.to_h) #=> {:foo=>1}
Baz = Struct.new(:foo)
baz = Baz.new(1)
p baz.to_h #=> {:foo=>1}
# so instead of writing something overly strict like:
def foo(opts)
raise ArgumentError, "opts must be a Hash" unless opts.is_a?(Hash)
# do stuff with opts
end
# we can go with the more versatile:
def foo(options)
if options.respond_to?(:to_h)
opts = options.to_h
else
raise TypeError, "can't convert #{options.inspect} into Hash"
end
# do stuff with opts
end
# %i: a literal for symbol array
# ==============================
p %i{hurray huzzah whoop} #=> [:hurray, :huzzah, :whoop]
# regexp engine is changed to Onigmo
# ==================================
# The is a fork of the Oniguruma regexp engine used by 1.9, with a few more
# features. More details at https://github.com/k-takata/Onigmo
# The new features seem Perl-inspired, this seems to be a good refrence:
# http://perldoc.perl.org/perlre.html
# (?(cond)yes|no)
# if cond is matched, then match against yes, if cond is false match against no
# cond refrences a match either by group number or name, or is a
# look-ahead/behind
# example only matches a trailing cap if there is a leading cap
regexp = /^([A-Z])?[a-z]+(?(1)[A-Z]|[a-z])$/
regexp =~ "foo" #=> 0
regexp =~ "foO" #=> nil
regexp =~ "FoO" #=> 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment