News for hackers. Stuff that matters.
Re:Ruby's Exceptional Creatures by stevebmark on Sunday January 28, 2024 @10:02PM (#39172251)
It's painful to see method_missing called out as a first class solution in the first creature https://www.exceptionalcreatures.com/bestiary/NoMethodError.... . "Practical Ruby" has three chapters dedicated to method_missing. "define_method" is more common these days and also painful to see.

Ruby gets a lot of criticism for embracing magic and indirection ("Ruby, the bad parts of Perl"). It has some good parts (no function colors, for example), but the ecosystem is the biggest problem by promoting magic. method_missing is not a good part of Ruby, it's a very bad part that you should only use if you know it's bad _and_ you know you still have to use it. I wish all tutorials would say this. "You can do this with Ruby, but don't, because your coworkers debugging an outage for an hour will hate you once they find out the bug is caused by method_missing".

Re:Ruby's Exceptional Creatures by RangerScience on Sunday January 28, 2024 @10:14PM (#39172318)
Respectfully mostly disagree. Ruby is full of sharp knives. Other languages have dull knives.

Writing code without thinking will cut you either way.

Things like method missing are exactly the right solution for a certain set of problems. If used thoughtfully, they’re amazing. If used thoughtlessly, bloody mess. But this is true in every language.

Re:Ruby's Exceptional Creatures by Groxx on Sunday January 28, 2024 @11:40PM (#39172753)
Where other languages have footguns, I've often described Ruby as offering footchainsaws, while tempting you to juggle them for fun. Far more damaging if you aim it at the wrong thing, but also far better at cutting down things that stand in your way.

I think it's the most enjoyable language I've used. With care and feeding it's amazing. I would absolutely not want to use it in a large company, that would be a walking nightmare.

Re:Ruby's Exceptional Creatures by vlz on Monday January 29, 2024 @12:39AM (#39173046)
Yes, I want to highlight what you say about large companies. ruby really shines, I think, if you are a solo dev or a small team, where everybody is on the same page and the codebase is completely understood. It is also good for libraries with a clear focus. For larger projects, it might work too, but you would need some good culture of "keep it simple" around it. A few ego-trips of supposedly smart devs and things can get hard to understand and hard to work with fast.
Re:Ruby's Exceptional Creatures by cutler on Monday January 29, 2024 @10:06PM (#39185950)
Here we go again with the Ruby isn't suitable for large projects nonsense. Github, Shopify and Stripe seem to be managing perfectly fine with Ruby, thank you very much.
Re:Ruby's Exceptional Creatures by vlz on Tuesday January 30, 2024 @11:15AM (#39191881)
Sure, but as I said, probably not without establishing some culture around it. Just for fun, let's look at shopify's Ruby Style Guide under "General"[0]:

    Avoid mutating arguments.
    Avoid monkeypatching.
    ...
    Avoid needless metaprogramming.
    Prefer public_send over send so as not to circumvent private protected visibility.
    Write ruby -w safe code.
    ...
[0]: https://ruby-style-guide.shopify.dev/#general
Re:Ruby's Exceptional Creatures by mokkol on Thursday February 01, 2024 @04:45AM (#39214247)
Every big company has (and if they don't, they should) style guides. In Ruby people tend to use something like Rubocop (which is a static code analyzer/linter) to agree on a style. That will even be added as a default in Rails 8.
Re:Ruby's Exceptional Creatures by busterarm on Sunday January 28, 2024 @10:30PM (#39172397)
If you want to be wowed by how incredible method_missing and define_method are, read through ActiveSupport and ActiveRecord's source code.

Early in my career I made my own toy ActiveRecord implementation and it's full of define_method and was literally the first time in my life that programming felt like a real superpower.

Re:Ruby's Exceptional Creatures by whakim on Monday January 29, 2024 @12:13AM (#39172923)
But we’ve learned over the decades that footguns should usually be avoided and discouraged rather than made easy to use like Ruby does. There’s a reason we aren’t writing GOTOs anymore, GC is a thing in all but the most performance-critical situations, and static typing is gradually winning.
Re:Ruby's Exceptional Creatures by stevebmark on Monday January 29, 2024 @12:02AM (#39172865)
Calling method_missing a sharp knife is like calling GOTO a sharp knife
Re:Ruby's Exceptional Creatures by pantulis on Monday January 29, 2024 @03:11AM (#39173946)
That's not a bad definition of GOTO.
Re:Ruby's Exceptional Creatures by djur on Monday January 29, 2024 @04:24AM (#39174380)
Right, and goto is still used regularly in production code.
Re:Ruby's Exceptional Creatures by jay-aye-see-key on Monday January 29, 2024 @01:12AM (#39173248)
I’ve always really disliked the sharp knives metaphor. A chef’s choice of knife doesn’t impact their coworkers, nor does it end up on the plate to a customer.

If we were chefs a knife would be your laptop, your editor, your cli tools. Not your programming language.

A better metaphor would be the lumber in a building or the soil in a garden. I don’t know what I’d call ruby in this metaphor, maybe “lightweight wood that splinters”…

Re:Ruby's Exceptional Creatures by tvink on Monday January 29, 2024 @11:45AM (#39178501)
The value of metaphors is not their ability to stay relevant at arbitrary inclusion of scope.

That being said, the original "Sharp Knives" piece is talking about powerful language features and whether to ban them in your kitchen, so yes, it has plenty of effect on their coworkers. Because it's a shared decision to not ban sharp knives from the kitchen, but trust and educate, and realize that people who're doing harmful things can do so with dull knives too. It's about the techniques you allow in your codebase, it doesn't propose that ruby is one "knife".

And programming language features does not, generally, end up on the plate of the customer either. The fact that this site is written in a language that allows even more powerful meta programming than ruby is not bleeding through in the sense that we now have the tools of the language available to us. We haven't been served sharp knives. We've been served the consequences of the engineering that went into it, and the people doing that engineering had the opportunity to leverage or ignore the sharp knives of the language. That language being lisp, I'm pretty sure they had at it.

Re:Ruby's Exceptional Creatures by chucke on Monday January 29, 2024 @04:20AM (#39174360)
Most other languages don't have knifes at all. What do you call the interface{} madness in go?
Re:Ruby's Exceptional Creatures by berkes on Monday January 29, 2024 @04:25AM (#39174397)
When you have small children, you put your sharp knives out of the way. If children get a bit older, you first teach em responsible use of a knife, then give a sharp pocket knife. And some kids not even that.

Point being: In Ruby, sharp knives are too accessible, come with no warning or even encouragement.

Yet contrary to actual sharp knives (or guns pointed at feet) the feedback loop is slow. When you shoot yourself in the foot, or cut your finger, you feel it right away and (hopefully) adjust before more accidents happen. With Ruby, a footgun is fired today. Or a sharp knife carelessly tossed in the bag yesterday. But you'll feel the pain in months or years only. And probably not even you, but the person who followed your follow up.

Sharp knives are cool. But they need education on their dangers and responsibilities.

Re:Ruby's Exceptional Creatures by groggo on Sunday January 28, 2024 @11:20PM (#39172645)
One rule I try to go by, and I feel like this should be a pretty moderate take but isn't actually that commonly stated:

If we're talking about Rails at least, then meta-programming/magic/indirection, all that should be very rare in application code. It makes sense sometimes in more abstract libraries, where you have to handle flexible problems, but in application code it's really worthwhile to just be straightforward and verbose.

Re:Ruby's Exceptional Creatures by seattle_spring on Monday January 29, 2024 @12:07AM (#39172887)
Every Rails app I’ve ever been introduced to had layers upon layers of “before_filter” and “after_filter”, deeply nested into 6+ subclasses of stuff. Whether or not this “should” or “should not” be in application code is beside the reality that it absolutely is all over application code. Makes it a fucking nightmare to debug.
Re:Ruby's Exceptional Creatures by groggo on Monday January 29, 2024 @12:29AM (#39172998)
Oh yeah, I guess it's better to limit the use of that. But I actually don't count using those as metaprogramming. It's just part of the framework, and you have to know about those features. Rails has a lot of magic and I think a lot of it is annoying and unnecessary. Using those features is one thing, but defining your own is too far imo, unless you're making a library.
Re:Ruby's Exceptional Creatures by vidarh on Monday January 29, 2024 @05:14AM (#39174701)
Rails, to me as someone who loves Ruby and use it for "everything" (including my editor, terminal, window manager), is a poster-child for poorly written Ruby.

It creates code bases that seems to have a tendency to turn into sprawling messes. I appreciate that it has driven a lot of people to Ruby, and in that way it's an amazing and impressive success, but recruiters get it somewhat right for the wrong reason when they sometimes list Rails as a "language".

I'm very happy to use "magic" in Ruby, but it should be high-impact, low code, and contained. E.g. I'm very comfortable with the "magic" in my window manager that turns event classes received from the X11 binding into method call on a target class, so that MotionNotify turns into target.on_motion_notify(event) without me having to specify every event class. It's simple, small, and let me cut a lot of code.

A lot of non-Rubyists would hate it, though.

The irony, though, about your complaint is that Rails code is some of the most verbose Ruby code you'll find, because it's geared at making cookie cutter creation of sites easy, and so a lot of patterns involve an excessive separation into vast amounts of low-impact, verbose classes that do way too little (the obsession with some Rails devs of writing "service classes" for things that should just have been a single method, for example, drives me crazy - yes there are valid uses of service classes, no almost no uses of them in Rails apps are reasonable)

Re:Ruby's Exceptional Creatures by AlchemistCamp on Sunday January 28, 2024 @10:31PM (#39172405)
I definitely prefer Clojure/Elixir-style macros to Ruby’s meta-programming features.

They’re still better than nothing, though. Method-mossing and friends played a critical role in making a framework like Rails possible in Ruby. In contrast, languages like Python and JavaScript just aren’t quite expressive enough to do it. A lot of energy went into attempts over the years, too! At best, something like Sails could get 2/3 off the way there and offer significant advantages on another axis, like making websockets first class.

Re:Ruby's Exceptional Creatures by Lutger on Monday January 29, 2024 @04:40AM (#39174476)
python has `__getattr__` (and a lot of other dunder magic), what is still missing? With named arguments and (kw)args, there is even more ergonomic magic I think. And django's orm also has similar magical abilities as activerecord.

I think a lot of the metaprogramming abilities Python has are just used less often than in Ruby. Not because it is less expressive, but because it has a culture of simplicity whereas brevity and generality are more valued in Ruby (Rails) culture.

Re:Ruby's Exceptional Creatures by AlchemistCamp on Monday January 29, 2024 @09:03AM (#39176342)
What Django doesn’t have and will never have is router or testing DSLs that are similarly ergonomic as Rails’s.

https://stackoverflow.com/questions/7079855/are-there-techni...

Re:Ruby's Exceptional Creatures by empthought on Monday January 29, 2024 @08:17PM (#39185176)
And thank goodness for that. It is impossible to reason about types in such monstrosities.
Re:Ruby's Exceptional Creatures by AlchemistCamp on Monday January 29, 2024 @11:22PM (#39186371)
If when looking at the pile of regexes which is Django’s router, your thought is “good, this way I can reason about types!”, then Ruby is definitely not the language for you.
Re:Ruby's Exceptional Creatures by empthought on Tuesday January 30, 2024 @07:00AM (#39189084)
No, I just implement a custom router class as the docs suggest, and move on with my life. It’s a much better use of my time than fighting mental-masturbation DSLs.
Re:Ruby's Exceptional Creatures by cutler on Monday January 29, 2024 @10:10PM (#39185975)
No, Python is much less expressive at the pure language level. Ruby is better designed for composability. It's the Lisp influence. Python completely lacks the Lisp, Smalltalk & Perl heritage which makes Ruby a really great language. Python lacks culture.
Re:Ruby's Exceptional Creatures by nf3 on Sunday January 28, 2024 @10:13PM (#39172312)
The page you linked to discusses NoMethodError, which is raised when a method is not found. Among other things it shows how method_missing is involved in searching for a method. Nowhere in the text is it promoted.
Re:Ruby's Exceptional Creatures by p_l on Sunday January 28, 2024 @10:09PM (#39172288)
method_missing is a tiny offense compared to what was getting popular at one point - creating classes by forking metaclass and injecting methods into... without knowing you're doing so (something IIRC got lost between people there...)

Result was objects that shared no structure, no field

Re:Ruby's Exceptional Creatures by pantulis on Monday January 29, 2024 @03:11AM (#39173949)
Do you mean the class << self pattern?
Re:Ruby's Exceptional Creatures by matheusmoreira on Monday January 29, 2024 @03:18AM (#39173991)
That's what I thought as well. If someone's opening metaclasses to define singleton methods they probably know all about the Ruby object model. I don't see how it could be done "without knowing you're doing so".
Re:Ruby's Exceptional Creatures by p_l on Monday January 29, 2024 @05:01AM (#39174615)
The people who did it first did understand the meta model.

Unfortunately some people started following without full understanding. I wasn't at forefront of things back then, so I only noticed when the people who did know better started to writing about abuse of this technique.

Re:Ruby's Exceptional Creatures by matheusmoreira on Monday January 29, 2024 @03:46AM (#39174163)
You keep saying method_missing is "bad" but what exactly is so bad about it?

The main complaint about method_missing has always been the inefficiency. The class hierarchy is walked every single time and only then is method_missing called. The use of define_method is a pretty neat solution to that problem. The method that wasn't found gets defined and it doesn't rely on method_missing again. Like a cache.

Re:Ruby's Exceptional Creatures by nomilk on Monday January 29, 2024 @04:13AM (#39174317)
The docs are just explaining how method resolution order works in ruby (i.e. explaining method_missing but not saying you should rush out and use it).

Personally, I've never used method_missing. Might have missed opportunities to write clever code, but I'm super happy being boring and explicit.

Tangentially, I've only used meta programming twice. Both where the alternative was cumbersome, and it was unlikely to cause confusion.

Ruby gives some exotic tools but doesn't force you to use them if you prefer not to.

Re:Ruby's Exceptional Creatures by vidarh on Monday January 29, 2024 @04:56AM (#39174578)
In every language without method_missing or equivalent, people end up writing custom dispatch based on message values sooner or later, sometimes re-implementing full method dispatch, and occasionally a full inheritance mechanism in the process.

If the set of messages you need to handle dynamically is to only ever be small, define_method() is the better choice, but when it is not, I'll take careful use of method_missing over some monstrosity that ends up emulating the same machinery with lots of extra code any day.

If you struggle with debugging due to method_missing, consider reviewing how you debug code, as it wouldn't even make my top ten of debugging challenges in the Ruby code I've worked on in the last 17 years of daily Ruby use.

Re:Ruby's Exceptional Creatures by sabellito on Monday January 29, 2024 @06:55AM (#39175278)
I have no idea what you're talking about in your first paragraph. I've put code in production in half a dozen languages, and ruby is, by a immense marging, the biggest offender on this. The only thing that comes close would be AOP in Java, that is bad but at least it's compile time magic with decent IDE support.

All the most heinous bugs I've had to deal with in my life were about magic in ruby. I've worked in 3 of the biggest rails codebases in the world, and in the end we had build checks to deny code with magic.

Software code should be optmised for reading and debugging, not looking nice for first time writes.

Re:Ruby's Exceptional Creatures by vidarh on Monday January 29, 2024 @08:06AM (#39175746)
Pretty much any switch/case or multipronged if is dispatch in disguise. Sometimes the switch/case/if is the right choice, sometimes it's making the code more convoluted. Once you step up a degree in complexity, you get e.g. lookup tables and class hierarchies to emulate more dynamic dispatch. Complex dispatch is all over the place in most large systems.

Ruby is "an offender" in this to you because you hate the pattern that untangles the huge unholy mess that less dynamic languages use instead. E.g. hacky workarounds like whole class hierarchies or (marginally better) maps from values you dispatch on to first order functions/closures

I have worked in over a dozen languages, and I've never seen a medium to large sized project where some form of dispatch mechanism hasn't been part of the codebase somewhere.

And I'll take the simplicity of dynamic dispatch over hand rolling verbose mappings any day.

> All the most heinous bugs I've had to deal with in my life were about magic in ruby. I've worked in 3 of the biggest rails codebases in the world, and in the end we had build checks to deny code with magic.

I have no like for Rails, it encourages a lot of awful shit, but I also find this really curious, because the backtraces will clearly indicate you've passed through method_missing, you can breakpoint requests and attach remote debuggers to in flight requests, and execute code in-context in those requests.

If that's too complex, sure, maybe a large Rails code base isn't right for you. I don't want to work on Rails codebases either, but because of Rails, not Ruby, nor because the dynamism makes it any harder to debug. > Software code should be optmised for reading and debugging, not looking nice for first time writes.

I agree,and it's exactly why I love Ruby.

Re:Ruby's Exceptional Creatures by tpm on Monday January 29, 2024 @05:10AM (#39174666)
These days (years) I work mostly in Java and would love to have method_missing or define_method. Of course I can do everything I want without them, but it's not fun.
Re:Ruby's Exceptional Creatures by erik_seaberg on Monday January 29, 2024 @05:50AM (#39174911)
Groovy has monkey patching and methodMissing (and propertyMissing) but runtime lookups make them slower than dispatch to classloader-defined methods.
Re:Ruby's Exceptional Creatures by cutler on Monday January 29, 2024 @10:15PM (#39186013)
Kotlin would be a good Java-compatible alternative with its extension functions.
Re:Ruby's Exceptional Creatures by ljm on Monday January 29, 2024 @06:01AM (#39174974)
It's not really any different to, say, lisp (which is lauded for its intuitive support of macros) and smalltalk (which is what ruby was directly influenced by).

As a dynamic language, Ruby gives you a lot of tools to create fully expressive code. This is just one aspect of it that you can, but don't have to, use.

Re:Ruby's Exceptional Creatures by postmodern_mod3 on Monday January 29, 2024 @11:36PM (#39186439)
"but the ecosystem is the biggest problem by promoting magic."

This argument isn't entirely true anymore. The Ruby ecosystem has mostly moved away from meta-programming, and embraced classical OOP. Rubyists now tend to avoid `method_missing` and `const_missing` when possible, and abandoned the craze of making everything a DSL. The most meta-programming that Rubyists still use on a regular basis is defining `self.included` on modules in order to inject other modules. Also, Rubyists have embraced API documentation, such as YARD, in order to document and communicate any "magic" that might exist or occur.