montroser
3 months ago
This is...not for me. It follows a big pattern in Ruby/Rails culture where to understand the code, you first have to understand the magic. And, it's never all that obvious where to go to try and understand the magic, because the magic itself has been imported by magic.
I once was hackathoning with a colleague who was trying to get me excited about Rails, and he said, "look how great this is -- if you want the idea of '1 day', you can just write `1.day`!". I opened up a irb to try it out, and it didn't work. We were both confused for a bit until he figured out that it was a Rails thing, not a Ruby thing. That Rails globally punches date/time methods into integers, which he thought was cool, and I thought was abhorrent. I asked, "okay, if I came across this code, how would I be able to know that it came from Rails?" He said, there wasn't any way to really trace a method to its source definition, you just kinda have to know, and I decided this whole thing was too much of a conflict with my mental model for how humans and code and computers should work together.
jaredcwhite
3 months ago
1.method(:day).source_location <= your friend was wrong shrug
Look, I'm not a big fan of all of Rails' monkeypatching. That's why I don't use Rails anymore, I use other Ruby frameworks like Bridgetown, Roda, and Hanami. But there's definitely a way to dive into the "magic" and find out what's going on.
montroser
3 months ago
Ah, that's good to know! Yeah, he was wrong about a lot of stuff, so that adds up. He ended up in jail for a stint.
hoipaloi
3 months ago
you monkeypatch over core methods like that they put you in jail right away no trial, no nothing. Metaprogrammers... we have a special jail for metaprogrammers. You're global variabling? Right to jail. You're using for loops instead of iterators? To jail right away. You're type checking by class... Jail. Abusing eval? Jail. You're using global variables like a drunken sailor? You right to Jail. You overuse class variables Jail. You underuse class variables believe it or not jail. You use too many tests also Jail, overuse underuse. You use define method and you could have created the methods explicitly? Believe it or not, jail right away. We have the best code monkeys in the world because of jail.
radanskoric
3 months ago
Woah, this thread escalated quickly.
jaredcwhite
3 months ago
whoa
bradgessler
3 months ago
Quite the plot twist there
nosman
3 months ago
how does this work if i import two different gems that both monkeypatch the same classes?
Even if you can see the source, it still seems difficult to understand where the monkeypatch came from if you have transitive dependencies and whatnot.
rokob
3 months ago
The last one wins
user
3 months ago
ryandv
3 months ago
[flagged]
isr
3 months ago
That's one thing which ruby unfortunately did not adopt from Smalltalk. In Smalltalk (at least, in the dialects I'm familiar with), the "method categories" metadata is used to signal that we're adding new methods (or overwriting existing ones) to classes that are outside the scope of this package (ie: classes you didn't create as part of your app).
That way, it's easy to trace, forwards (from package to all the methods it introduces) & backwards (from method to package), who introduced a method, where, and why.
Other than that, I think a lot of this aversion to "ruby magic" is a bit overblown. The ability to cleanly remold any part of the system with minimal friction, to suit the app you're building right now - that's a KEY part of what makes it special.
Its like all these polemics warning wannabe lispers away from using macros. Lisp, Smalltalk, and ruby, all give you very powerful shotguns to express your creative ideas. If you can't stop blowing your own foot off, then pick a different language with a different paradigm.
dragonwriter
3 months ago
> That's one thing which ruby unfortunately did not adopt from Smalltalk. In Smalltalk (at least, in the dialects I'm familiar with), the "method categories" metadata is used to signal that we're adding new methods (or overwriting existing ones) to classes that are outside the scope of this package (ie: classes you didn't create as part of your app).
> That way, it's easy to trace, forwards (from package to all the methods it introduces) & backwards (from method to package), who introduced a method, where, and why.
Doesn't Method#source_location in Ruby provide a mechanism for this?
Though, in modern (>3.x) Ruby, its probably better to avoid monkey-patching unless you need to override behavior exposed to consumers that aren't opting in, and just use Refinements that consumers can opt-in to using.
igouy
3 months ago
> If you can't stop blowing your own foot off…
I can. It is, of course, those who worked on the project before me, that expressed their all-too-human over-confidence in their own abilities and judgement.
And then we would spend-a-weekend to rip-out the changes they'd made to Smalltalk system classes, that conflicted with the version upgrade.
(Something about the narcissism of small differences.)