Reputation: 155
The following code works:
class String
def color(code)
"\e[#{code}m#{self}\e[0m"
end
end
puts "Anything".color(93)
I want to be able to do:
puts "Anything".red
by catching the red
as a string, and then giving it to a case-block as follows:
class String
case **?WHAT?**
when "red" then color(91)
else color(0)
end
end
but it doesn't work. Is there a smart way to do this? How can I get the method name and use it in a case block?
Upvotes: 1
Views: 313
Reputation: 155
Thanks for your effort. I've found a Solution based on your last code piece and a bit of asking here and there:
class String
def color(code)
"\e[#{code}m#{self}\e[0m"
end
colors = { black: 30, red: 31, green: 32, orange: 33, blue: 34, purple: 35, cyan: 36, gray: 37, white: 97,
lgray: 90, lred: 91, lgreen: 92, yellow: 93, lblue: 94, lpurple: 95, lcyan: 96 }
colors.each {|name, value| define_method(name) do; color(value); end; }
end
As you can see, I didn't catch the method's name but used a hash to create definitions via 'define_method'. Its much smaller code and nice to read than using case-blocks. :D
People told me to use a Module instead of patching core classes but for personal use its ok I think.
Upvotes: 0
Reputation: 19308
I think you're looking for method_missing
and I've presented a solution below. This is great for learning, but you probably don't want to monkey patch String
with method_missing
if you're working on a production codebase!
class String
def color(code)
"\e[#{code}m#{self}\e[0m"
end
private
def method_missing(name, *args)
return send(:color, 91) if name == :red
send(:color, 0)
end
end
p "Anything".red # => "\e[91mAnything\e[0m"
p "Anything".color(93) # => "\e[93mAnything\e[0m"
p "Anything".magenta # => "\e[0mAnything\e[0m"
Here is another way to solve the problem with define_method
:
class String
def self.color_mapping
{
red: 91,
blue: 100
}
end
def color(code)
"\e[#{code}m#{self}\e[0m"
end
color_mapping.each do |c, v|
define_method(c) do
color(v)
end
end
def method_missing(name, *args)
send(:color, 0)
end
end
Upvotes: 2