> eval, send, method_missing, define_method , as a non-rubyist how common are these in real-world code?
Quite a lot, that's what allows you to build something like Rails with magic sprinkled all around. I'm not 100% sure, but probably the untyped JSON ingestion example uses those.
Remove that, and you have a very compact and readable language that is less strongly typed than Crystal but less metaprogrammable than official Ruby. So I think it has quite a lot of potential but time will tell.
> Quite a lot, that's what allows you to build something like Rails with magic sprinkled all around
True, but I'd point out that use in frameworks/DSLs etc is the main place you see those things, and most of the code people write in their own projects don't use these.
In my experience (YMMV), eval and send are rare outside of things like, slightly cowboy unit tests (send basically lets you call private methods that you shouldn't be able to call, so it's considered terrible form to use it 'IRL'. Though there is a public_send which is a non-boundary-violating version too).
Also in my opinion, unless you're developing a framework or something, metaprogramming (things like define_method etc) are Considered Harmful 95% of the time (at least in Ruby), as I think only about 5% of Ruby developers even grok it enough to work in a codebase with that going on. So while it might seem clever to a Staff Eng with 15 years of Ruby experience, the less experienced Rubyist who is going to be trying to maintain the application later is going to be in pain the whole time due to not being able to find any of the method definitions that appear to be being called.
I disagree, I use metaprogramming in application code quite regularly, although I tend to limit myself to a single construct (instance_eval) because I find that makes things more manageable.
In my opinion the main draw of Ruby is that it's kind of Lisp-y in the way you can quickly build a metalanguage tailored to your specific problem domain. For problems where I don't need metaprogramming, I'd rather use a language that is statically typed.
The two are not mutually exclusive. On many occasions I've used C# to define domain-specific environments in which snippets of code, typically expressions, are compiled and evaluated at runtime, "extending the language" by evaluating expressions in the scope of domain-specific objects and/or defining extension methods on simple types (e.g., defining "Cabinet" and "Title" properties on the object and a "Matches" extension method on System.String so I can write 'Cabinet.EndsWith("_P") || Title.Matches("pay(roll|check)", IgnoreCase)').
I don't think instance_eval is too nasty. The toughest "good" codebase I've worked in was difficult because it used method_missing magic everywhere, which built tons of methods whose existence you had to just infer, based on configuration stored in a database. So most method calls could not be "command clicked" or whatever to jump to their definition, because none were ever defined.
Quite a lot, that's what allows you to build something like Rails with magic sprinkled all around. I'm not 100% sure, but probably the untyped JSON ingestion example uses those.
Remove that, and you have a very compact and readable language that is less strongly typed than Crystal but less metaprogrammable than official Ruby. So I think it has quite a lot of potential but time will tell.