Flowdock

Good notes posted to Ruby

RSS feed
August 17, 2008
4 thanks

Regexes with groups and split

When you use a Regex with capture groups, all capture groups are included in the results (interleaved with the “real” results) but they do not count for the limit argument.

Examples:

"abc.,cde.,efg.,ghi".split(/.(,)/)
=> ["abc", ",", "cde", ",", "efg", ",", "ghi"]
"abc.,cde.,efg.,ghi".split(/(.)(,)/)
=> ["abc", ".", ",", "cde", ".", ",", "efg", ".", ",", "ghi"]
"abc.,cde.,efg.,ghi".split(/(.(,))/)
=> ["abc", ".,", ",", "cde", ".,", ",", "efg", ".,", ",", "ghi"]
"abc.,cde.,efg.,ghi".split(/(.(,))/, 2)
=> ["abc", ".,", ",", "cde.,efg.,ghi"]
"abc.,cde.,efg.,ghi".split(/(.(,))/, 3)
=> ["abc", ".,", ",", "cde", ".,", ",", "efg.,ghi"]
August 15, 2008
4 thanks

Cheking if a number is prime?

It’s a class for generating an enumerator for prime numbers and traversing over them.

It’s really slow and will be replaced in ruby 1.9 with a faster one.

Note: if you just want to test whether a number is prime or not, you can use this piece of code:

class Fixnum
  def prime?
    ('1' * self) !~ /^1?$|^(11+?)\1+$/
  end
end

10.prime?
August 15, 2008
8 thanks

Optional Argument for detect/find [Not Documented]

detect/find’s optional argument lets you specify a proc or lambda whose return value will be the result in cases where no object in the collection matches the criteria.

classic_rock_bands = ["AC/DC", "Black Sabbath","Queen", "Ted Nugent and the Amboy Dukes","Scorpions", "Van Halen"]
default_band = Proc.new {"ABBA"}
classic_rock_bands.find(default_band) {|band| band > "Van Halen"}
=> "ABBA"

or

random_band = lambda do
  fallback_bands = ["Britney Spears", "Christina Aguilera", "Ashlee Simpson"]
  fallback_bands[rand(fallback_bands.size)]
end
classic_rock_bands.find(random_band) {|band| band > "Van Halen"}
=> "Britney Spears"
August 15, 2008
3 thanks

Convert a Hash to an Array of Arrays using map

Although you’ll always have to_a and it’s faster, this trick is too cool to ignore…

When the block is omitted, collect or map uses this implied block: {|item| item}, which means when applied on an hash without a block, collect/map returns an array containing a set of two-item arrays, one for each key/value pair in the hash. For each two-item array, item 0 is the key and item 1 is the corresponding value.

burgers = {"Big Mac" => 300, "Whopper with cheese" => 450, "Wendy's Double with cheese" => 320}

burgers.map
=> [["Wendy's Double with cheese", 320], ["Big Mac", 300], ["Whopper with cheese", 450]]

see also:

August 15, 2008
3 thanks

Using any? on Empty Arrays and Hashes

When applied to an empty array or hash, with or without a block, any? always returns false. That’s because with an empty collection, there are no values to process and return a true value.

August 15, 2008
3 thanks

Testing Arrays for nils with Enumerable#all?

When the block is omitted, all? uses this implied block: {|item| item}.

Since everything in Ruby evaluates to true except for false and nil, using all? without a block on an array is effectively a test to see if all the items in the collection evaluate to true (or conversely, if there are any false or nil values in the array).

Using all? without a block on a hash is meaningless, as it will always return true.

August 15, 2008
4 thanks

Using all? on Empty Arrays and Hashes

When applied to an empty array or hash, with or without a block, all? always returns true. That’s because with an empty collection, there are no values to process and return a false value. so, watch out, if your array or hash is empty for any reason you will get a true which might not be what you expect it to be.

August 14, 2008 - (v1_8_6_287)
11 thanks

Convert an Array to a Hash

The Hash.[] method converts an even number of parameters to a Hash. (The Hash[] method depends on the Hash class, but don’t confuse the method with the class itself). For example:

Hash['A', 'a', 'B', 'b']
# => {"A"=>"a", "B"=>"b"}

You can convert an array to a hash using the Hash[] method:

array = ['A', 'a', 'B', 'b', 'C', 'c']
hash = Hash[*array]
# => {"A"=>"a", "B"=>"b", "C"=>"c"}  

The * (splat) operator converts the array into an argument list, as expected by Hash[].

You can similarly convert an array of arrays to a Hash, by adding flatten:

array = [['A', 'a'], ['B', 'b'], ['C', 'c']]
hash = Hash[*array.flatten]  
# => {"A"=>"a", "B"=>"b", "C"=>"c"}

This also comes in handy when you have a list of words that you want to convert to a Hash:

Hash[*%w(
  A a
  B b
  C c
)]
# => {"A"=>"a", "B"=>"b", "C"=>"c"}
August 14, 2008
5 thanks

Convert an Array of Arrays to a Hash using inject

Converting an array of arrays to a hash using inject:

array = [['A', 'a'], ['B', 'b'], ['C', 'c']]

hash = array.inject({}) do |memo, values|
  memo[values.first] = values.last
  memo
end

hash
# => {'A' => 'a', 'B' => 'b', 'C' => 'c'}