Home
  • About
  • Software
  • Contact
  • Rubyisms: Using inject to validate element types in an array
    March 3rd, 2010

    I’m writing a distributed system simulator in Ruby and had a need to verify that an array contained only integer process ID’s, and no elements of any other type. Using Ruby’s Enumerable#inject function, this is a wonderfully quick one-liner.

    >> a = [1,2,3]
    => [1, 2, 3]
    >> a.inject(true) do |result, element| result && element.is_a?(Fixnum) end
    => true
    >> b = [1,"Hi",3]
    => [1, "Hi", 3]
    >> b.inject(true) do |result, element| result && element.is_a?(Fixnum) end
    => false
    

    Edit: After I posted this, Robert Riemann pointed out that Enumerable#inject iterates over the entire array even if the first value in the array is not an integer. This is easily confirmed as follows:

    >> a.inject(true) do |result,element| puts "Next element"; result && element.is_a?(Fixnum) end
    Next element
    Next element
    Next element
    => false
    

    So, inject is not what we’re looking for in this case. Later, Martin Vidner offered a solution using Enumerable#all?:

    >> a = [1,2,3]
    => [1, 2, 3]
    >> a.all? do |e| e.is_a?(Fixnum) end
    => true
    >> b = [1,"Hi",3]
    => [1, "Hi", 3]
    >> b.all? do |e| e.is_a?(Fixnum) end
    => false
    

    Using all?, we see that processing stops after a non-integral value is encountered:

    >> b = [1,"Hi",3]
    => [1, "Hi", 3]
    >> b.all? do |e| puts "Next element"; e.is_a?(Fixnum) end
    Next element
    Next element
    

    Thanks to both Robert and Martin for pointing out the problem in my original solution.

    Category: Ruby
    Tags: Ruby, rubyisms
    Permalink
    No Comments »
    Rubyisms: Quick Regular Expression Captures
    December 24th, 2009

    As part of my Christmas reading, I am currently devouring the fantastic Ruby Best Practices from O’Reilly, which is packed with a plethora of tricks that remind you on each page why Ruby programming is joyous and beautiful.

    The book pointed out one particular trick of which I wasn’t aware. When you want to capture a regular expression match from a string, you can simply index into the string with the regular expression, and the capture number.

    >> str = "First name: Jeff      Last name: Shantz"
    => "First name: Jeff      Last name: Shantz"
    >> first_name = str[/:\s*(\w+)[^:]+:\s*(\w+)/,1]
    => "Jeff"
    >> last_name = str[/:\s*(\w+)[^:]+:\s*(\w+)/,2]
    => "Shantz"
    
    Category: Ruby
    Tags: Ruby, rubyisms
    Permalink
    1 Comment »
    Archives
    • March 2010
    • December 2009
    Categories
    • Ruby
    RSSMy Twitter Feed
    • And just like that... the eureka moment. Proof complete. Q.E.D. bitches. (http://xkcd.com/622) about 2 days ago from Echofon
    • Ah yes, Saturday night at the school, working on an assignment. Good times. about 3 days ago from Echofon
    • The new low in political correctness: an argument to make O Canada "gender neutral." Disappointed in the PM. http://bit.ly/aVfQMM about 6 days ago from Echofon
    • @mvidner Ah yes, thank you. I'll post an update later. 06:57:45 PM March 03, 2010 from Echofonin reply to mvidner
    • @salout_de True, but I didn't claim it was efficient -- just quick and easy. :) In truth, the arrays I'm working with are quite short. 04:37:20 PM March 03, 2010 from Echofonin reply to salout_de
    Copyright © 2009, Jeff Shantz.  All rights reserved.