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.
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.
There is even a fucking issue on the ruby-lang issue tracker from two years ago griping about this dark corner of the language [1].
No matter though, I don't expect average laymen to delve into this level of detail nor assess the veracity of statements at this layer.
Most Rubyists at this point are at the level of "terminal dumbfuck," and are indistinguishable from a bartender who stumbled into a 16 week bootcamp for blockchain development. The one silver lining of the great AI Happening is that these people will be put back into their place.
irb(main):001\* class Foo
irb(main):002" class_eval <<-RB
irb(main):003" def foobar()
irb(main):004" puts "foobar"
irb(main):005" end
irb(main):006\* RB
irb(main):007> end
=> :foobar
irb(main):008> Foo.new
=> #<Foo:0x00007ff5c1a8c190>
irb(main):009> Foo.new.method(:foobar)
=> #<Method: Foo#foobar() (eval at (irb):2):1>
irb(main):010> Foo.new.method(:foobar).source_location
=> ["(eval at (irb):2)", 1]
[0] https://github.com/rails/rails/blob/9b054c66d4fc5ec526cff356...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.
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.)
> 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.
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.