[HN Gopher] An Introduction to Metaprogramming in Ruby
___________________________________________________________________
An Introduction to Metaprogramming in Ruby
Author : unripe_syntax
Score : 69 points
Date : 2023-07-26 11:18 UTC (1 days ago)
(HTM) web link (blog.appsignal.com)
(TXT) w3m dump (blog.appsignal.com)
| mvdtnz wrote:
| The only guide to meta programming I give to developers at my
| company is "don't use it, it will not pass code review".
| iraliaf wrote:
| why?
| the_sleaze9 wrote:
| It's a foot gun (incoming strong opinion)
|
| The single most difficult thing in software development is
| the fact that the system doesn't exist, it is defined by
| mystical incantations, and we work on that invisible system
| by changing the instructions to build it.
|
| Anything that makes the understanding or "building" that
| system mentally is no-go.
|
| Flashback to one of my favorite debugging stories where an
| entire java code-base was meta-programmed into existance at
| runtime and would constantly throw errors to lines of files
| that didn't exist.
| actualwill wrote:
| Ruby meta programming is awesomely powerful, but also one of the
| main reasons I never want to work in another's Ruby codebase
| again. There is always some developer who read some article like
| this and invents their own DSL to solve a problem that didn't
| need one. It's pure pain to debug it.
| jweir wrote:
| I love Ruby and we use Ruby and we do not allow meta-
| programming. Too difficult to maintain.
|
| Even `send` is frowned upon, but allowed under some
| circumstances.
| actualwill wrote:
| If you have some group that all understands and checks each
| other from the beginning, Ruby is probably great.
|
| However it was every startups default choice for a while, and
| those code bases get wrecked and have no oversight until way
| later. A lot of bad ideas becomes foundational. This scenario
| is far more common than good Ruby code bases. It's just
| easier to rule out Ruby when looking for new jobs.
| f6v wrote:
| Classic: saving two lines of code, but completely breaking
| maintainability.
| tremon wrote:
| Exhibit #1: rake's DSL syntax. It allows "neat" syntax
| abominations like rule :name, [:param] =>
| [:dep1, 'dep2'] do |t|
|
| where every argument except the name can either be missing,
| single (value) or multiple (array). Sure, it has the
| "advantage" that it's syntactically valid Ruby code, but it
| then requires some 70 lines of awful code to actually parse
| that data into a usable construct: https://github.com/ruby/ra
| ke/blob/7b50e9dc37abc57fd365c16cb1...
| UncleOxidant wrote:
| I feel the same. For my own projects where it's only me working
| on the code it can be really nice, powerful and big
| productivity boost. But if you start having multiple people on
| the codebase it's not going to be fun to debug.
| Alifatisk wrote:
| I learned how fun metaprogramming is but also realized that it is
| a double edged sword, so if I want the codebase to be
| maintainable then I'd stay away from metaprogramming as much as
| possible, it's a hell to debug, but also very powerful when you
| want to construct your own DSL etc.
| ye-olde-sysrq wrote:
| Ruby is the only language where extensively deep magic feels okay
| to me, for some reason.
|
| I don't like it in python, I don't like it in Java.
|
| But e.g. in Rails, sure I bump my head sometimes, but overall I
| like how magical Rails feels because it lets me go so fast.
|
| Maybe it's because Ruby alone is willing to sacrifice so much
| speed (though not THAT much vs python tbh) and is willing to go
| all-in on it, that they enable magic to be so deeply magical that
| it can deliver adequate value to compensate for being more
| inscrutable?
|
| Whereas other languages' metaprogramming systems keep you a
| little more leashed.
| vlunkr wrote:
| Makes sense. In some ways there's less magic to ruby, because
| it's not using macros, templates, reflection, generics etc. In
| other languages you're stepping out of "normal" code into
| "special" code to make the magic work.
| pseudocomposer wrote:
| Rust's macro system is the first I've seen with the same
| potential. But of course, an equal to Rails has yet to surface;
| and even if one does, being a compiled language still
| counteracts a lot of its ergonomics.
| ramenbytes wrote:
| Excuse me netizen, do you have a moment to talk about our
| Lord and Savior, Lisp?
| pseudocomposer wrote:
| With Lisp, is it even metaprogramming? Or maybe everything
| is metaprogramming...
| interstice wrote:
| I loved it.. until something broke and searching a method name
| didn't work because it was using dynamic method names. A full
| day of unpacking the Spree Commerce shipping system put me off
| a bit.
| RussianCow wrote:
| I'm not super proficient with Ruby/Rails but we use it for
| our backend at work, and this reflects a large portion of the
| time I've spent using it. People who use Rails every day take
| for granted just how much magic there is and how confusing it
| can be for someone less experienced with it.
| acchow wrote:
| Ruby metaprogramming breaks `grep` and static analysis tools.
| This is a no-go for any large project for me
| ye-olde-sysrq wrote:
| Yeah sure - it absolutely has drawbacks. I too have spent
| time going "what the heck is this actually doing". But man
| when you're not debugging one of those wonky things, Rails
| just feels like programming with a rocket strapped to your
| chair.
|
| Is it the most maintainable code? No. Is it the easiest to
| understand? It depends tbh. Rails provides so much out-of-
| the-box stuff that lots of rails apps end up looking
| sufficiently similar, especially if they're small-to-medium-
| sized. But yes you can end up writing some dreadful spaghetti
| without a bit of discipline, but imo that's true of python
| and (node) js as well.
|
| But damn is it SO fast to get up and going. And given
| product-market fit is why most projects and products fail,
| it's hard to argue against using Rails for me, since if I'm
| even still here to complain about it later, that's already a
| win.
| Alifatisk wrote:
| > Rails just feels like programming with a rocket strapped
| to your chair.
|
| I know this feeling!
| rakoo wrote:
| Same for me. I am now happily using Crystal as a ruby-with-a-
| compiler and the joys of the beginning are coming back.
| fishtoaster wrote:
| Ruby's metaprogramming allows you to create _really_ nice,
| ergonomic abstractions. I can write `has_one :posts` in a User
| model class in Rails and a _ton_ of useful functionality pops
| into existence.
|
| On the other hand, that deep magic metaprogramming can be
| _really_ hard to follow if you need to understand how it works.
| Tracing back through (or even debugging) a metaprogramming-
| heavy codebase is a nightmare.
|
| I'd argue that deep magic metaprogramming is great for when you
| have abstractions you almost never need to dig into. Rails is
| great because it's relatively rare that I need to go spelunking
| in the rails codebase itself (and thus understand the deep
| magic). Instead, I can rely on a huge pile of documentation,
| stack overflow answers, conference talks, etc to figure out how
| to use rails' abstractions (like `has_one :posts`) without
| needing to understand their implementation.
|
| On the other hand, the average production codebase should
| minimize their use of metaprogramming. When I don't understand
| how Joe's `Whatsit` interface works, I'm much more likely to
| need to dig into Joe's code to understand how to use that
| abstraction. If I have to understand Joe's deep magic every
| time I do that, it's a net loss.
| hiharryhere wrote:
| It's not even has_one :posts, it's has_one :post because of
| even more rails pluralization magic :)
|
| Agree with everything you said
| rezonant wrote:
| could be a model called Posts and plural is "postses" :-)
|
| (disclaimer: I do rails all day)
| cutler wrote:
| Try Clojure. It takes metaprogramming to a level higher than
| Ruby's version.
| kubectl_h wrote:
| I've worked with Ruby for over fifteen years off and on and the
| last seven exclusively -- in a large codebase with a fair
| amount of metaprogramming. We've onboarded engineers, junior
| and senior, who previously have never used Ruby and it's been
| interesting to see who does and doesn't have a hard time with
| it. It doesn't seem to match overall experience and skill
| level. It's more of a sense that people with patience and a
| kind outcome oriented approach (over fixating on why something
| is done a certain way) will have an easier time unwinding the
| complexity.
|
| One thing I've noticed, and this is something that seems to
| bother non-Ruby engineers, is the people that flourish in a
| complex Ruby application prefer to read code over
| documentation.
___________________________________________________________________
(page generated 2023-07-27 23:00 UTC)