Modifying existing classes in ruby
I’m currently refreshing my ruby skills as it’s not something I’ve looked at for a while (I primarily work with php and javascript). One of the features that I always find interesting in ruby is the ability to open up an existing class and modify it. For example in one of the programming exercises I was doing I needed to apply a regex to each line of a file. I wanted to include the line number of any matches but the grep method in the File class didn’t provide for this. So:
class File
def grep_with_line_number (pattern, &block)
# This bit filters with the pattern but has the index
lines = enum_for(:each_with_index).select do |line,|
line =~ pattern
end
# grep executes a block, so this method should too
if block_given?
lines.each do |line, number|
block.call(line, number)
end
end
lines
end
end
This is cool I can now trivially find matching lines with:
File.open('blah.txt', 'r') do|input_file|
input_file.grep_with_line_number /Steve/i do |line, line_number|
puts "line #{line_number + 1} ===> #{line}"
end
end
This means we can monkey patch ruby with basically anything we want. From a code maintenance point of view I’m not sure I’d want to do this on any large project but it’s a nice feature to have for smaller things. As always though with this much power comes great responsibility:
class Fixnum
def ==(other)
other < self
end
def +(numeric)
self
end
end
puts 1 == 1 # false
puts 2 == 1 # true
puts 1 + 2 # 1
puts 1 + 3 # 1
Yup. This is a thing. Bye bye maths!