Skip to content

Instantly share code, notes, and snippets.

@tamalw
Created February 19, 2013 05:38
Show Gist options
  • Save tamalw/4983377 to your computer and use it in GitHub Desktop.
Save tamalw/4983377 to your computer and use it in GitHub Desktop.
Deeper into blocks
# Blocks are a way of "injecting" code to run in the context of the original method.
# Side note: we can open an existing class and add methods.
# Let's make the String class awesome, don't worry about the blocks yet
class String
def hax0rify
replac0rs = {
'o' => '0',
'a' => '4'
}
h4x0r3d = self.downcase
replac0rs.each do |original, replacement|
h4x0r3d.gsub!(original, replacement)
end
h4x0r3d.chars.map { |c| rand(10) > 5 ? c.upcase : c }.join
end
end
foo = "Hello my fellow Americans.".hax0rify
foo # => "Hell0 mY FElL0w 4meriC4nS."
# This is great, but what if we want the user to decide what the replacement hash should be?
# We can pass the replacement hash to the user for modification by using yield
# The user "catches" the hash through the pipes and modifies it
class String
def hax0rify # !> method redefined; discarding old hax0rify
replac0rs = {
'o' => '0',
'a' => '4'
}
yield replac0rs
h4x0r3d = self.downcase
replac0rs.each do |original, replacement|
h4x0r3d.gsub!(original, replacement)
end
h4x0r3d.chars.map { |c| rand(10) > 5 ? c.upcase : c }.join
end
end
foo = "Hello my fellow Americans.".hax0rify do |replacement_hash|
replacement_hash['e'] = '3'
replacement_hash['l'] = '1'
end
foo # => "H3110 mY F3110w 4M3ric4ns."
# So the object replac0rs INSIDE the method, gets passed to the block as replacement_hash and the object is modified
# when the block returns, the modified object is used INSIDE THE METHOD. HOLY CRAP THIS IS SOME POWERFUL SHIT!
# Iterators like each and map work much the same way
# Let's make our own, this time we'll pass two values to the block
# Ignore the horrible duplication of existing methods
class String
def modify_each_letter_with_index
new_string = ''
i = 0
while i < self.length
new_string << yield(self[i].chr, i)
i += 1
end
new_string
end
end
foo = "Hello my fellow Americans.".modify_each_letter_with_index do |letter, index|
if index % 3 == 0
letter.upcase
else
letter * 2
end
end
foo # => "HeellLoo Myy FeellLooww AAmmErriiCaannS.."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment