with cats 😸
(at compile time)
class Cat def meow print "meow meow" end end dixie = Cat.new dixie.meow # "meow meow"
class Cat def meow print "meow meow" end end dixie = Cat.new dixie.hiss # "undefined method `hiss' for # #<Cat:0x000001028c22a8> (NoMethodError)"
class Cat def meow print "meow meow" end def method_missing(method) print "BOO HISS" end end dixie = Cat.new dixie.hiss # "BOO HISS"
This works in Ruby because of
object inheritance hierarchy 👩👩👦👦
"monkey patching" 🙉
class String def meow print "meow, I am definitely cat" end end "some random string".meow # "meow, I am definitely cat"
Other languages support metaprogramming, too. Lisps have macros, Java has reflection, etc.
However... metaprogrammed code is often harder to read. Behaviour can change from compile time to runtime.
Metaprogramming is useful in some cases, such as DSLs (domain-specific languages), ex. Rails + ActiveRecord:
Member.find_by_email("firstname.lastname@example.org") Venue.find_by_name("Songkick") Cat.find_by_color("calico")