I wouldn't say it's really a beauty of the language, it may have been the original design intent but time has shown what's actually maintainable.
The reality is that there certainly are enthusiast programmers who can thrive with the lightweight elegance of stock Ruby, but most people writing code professionally aren't enthusiast programmers under ideal conditions. Everything is always a little more distracted, a little less well-defined, and a little more coupled to legacy than anyone would want. And those are the conditions where I want my tools working as hard as possible, automatically, for me / my teams.
An example I always used to use was something like a method that could take a single item or a collection:
def unpicky(something)
if something.respond_to?(:each)
# unpack using each or recurse to something.each do |item| unpicky(item) end
else
# main body
end
endAnd T-Ruby apparently provides interfaces to avoid needing to do this at all (assuming both sides are written in T-Ruby I assume) https://type-ruby.github.io/docs/learn/interfaces/defining-i...
...which is awesome!
As for authoring classes, respond_to_missing?/method_missing should be rare, usually in a situation where its the only way to accomplish something. There's never been a reason to write something like:
class Car
def respond_to_missing?(name, priv)
[:color, :color=].include?(name)
end
def method_missing(name, *args, &block)
if name == :color
@color
elsif name == :color=
@color = args.first
end
end
end
Instead of class Car
def color; @color; end
def color=(value); @color = value; end
end
Or, more idiomatically class Car
attr_accessor :color
end
And for that last case, T-Ruby apparently covers it with: class Car
attr_accessor :color: String
end