Skip to content

Instantly share code, notes, and snippets.

@atcruice
Last active August 29, 2015 14:07
Show Gist options
  • Save atcruice/9745362bf925039010ef to your computer and use it in GitHub Desktop.
Save atcruice/9745362bf925039010ef to your computer and use it in GitHub Desktop.
ruby_nuggets.map { | nugget | dʒɪst(nugget) }

All variable names have been changed to protect the innocent. Likeness to any variables presently in or out of scope is purely coincidental.

Got caught by the following snippet this morning:

# given a heterogeneous array,
# I'm only interested in positive integers
# and I really only need one
first_positive_integer = array.reduce([]) do |memo, obj|
  memo << obj.to_i if obj.to_i > 0
end.first

Note: to_i returns 0 if it can't parse an integer from the start of whatever it's called on.

Upon testing I was suprised to find that Ruby slapped me with
NoMethodError: undefined method 'first' for nil:NilClass
depending on the non-numerical contents of array.

A quick jump across to Dash helped me realise that I had forgotten how reduce/inject actually replaces memo with the result of the block - the block yields nil if the conditional fails.
After a swift facepalm I looked at possible fixes:

# actually push the nil and then filter
first_positive_integer = array.reduce([]) do |memo, obj|
  memo << (obj.to_i if obj.to_i > 0)
end.reject(&:nil?).first
# extract the accumulator
memo = []

array.map do |obj|
  memo.push(obj.to_i) if obj.to_i > 0
end

first_positive_integer = memo.first

I chose the latter for readability.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment