implicit conversions in ruby
2025-02-08
Say you’re working with a directory:
dirpath = '.'
dir = Dir.open(dirpath)
And you want to do something with the files in that directory:
dir.each do |filename|
filepath = "#{dirpath}/#{filename}"
p File.read(filepath) if File.file?(filepath)
end
But you don’t want to keep having to interpolate strings, so you create a class to make your life easier:
class MyFile
attr_reader :path
def initialize(dirpath, filename)
@path = "#{dirpath}/#{filename}"
end
end
dir.each do |filename|
f = MyFile.new(dirpath, filename)
p File.read(f.path) if File.file?(f.path)
end
Ruby has a built-in feature called “implicit conversion”, where it will try to perform a conversion if certain methods on the class exist. Which means we can do this instead:
class MyFile
def to_str
@path
end
end
dir.each do |filename|
f = MyFile.new(dirpath, filename)
p File.read(f) if File.file?(f) # no need to call #path anymore
end
File.read expects a string, but we pass it an instance of MyFile, which has a to_str method - so Ruby performs an implicit conversion and treats it like a string.
I think I like this, but I’m sure there’s a ton of reasons why you wouldn’t want this kind of implicit behaviour.