with cats 😸
(at runtime)
(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 👩👩👦👦
and
"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("denise@codebar.io")
Venue.find_by_name("Songkick")
Cat.find_by_color("calico")