Settings

Theme

Moment of Ruby: An Argument for Nothing

aha.io

70 points by zemptime · 15 comments

Reader

8 threads
matharmin

It's an interesting trick, but for a setter method you really need to use `def cloaking=(value)` instead of overloading the same method. It would help to give a more realistic example for where this technique can be useful.

  • the_sleaze_

    Agreed. Ruby is a very sharp tool and its expressiveness can lead to overly clever expressions of creativity.

    Better to use `defined?` keyword for nil checking. It does what it says on the box.

  • shevy-java

    I somewhat agree with you here. I find it easier to read when a '=' is used.

    At the same time I also understand the idea behind:

        def colour(xyz = :green)
    
    The idea would be to use something in a toggle state.

    I sometimes use a similar, but simpler pattern, though I also tend to use explicit method names. But for instance:

        enable(:colours)
        enable :colours
        enable_colours
        disable_colours # etcc
    
    Personally I prefer the longer variants, e. g. enable_colours and disable_colours (without trailing (); if people prefer US spelling the method names could be enable_colors etc.. it is really the very same point anyway). I do, however had, also sometimes use a more generic top-level entry point such as enable. I use that for my pseudo-shell replacement for bash, written in ruby too. For instance:

        enable :windows_configuration
        enable :colours
        enable :systemd # and so on and so forth.
    
    I mostly do this so I have an easier time remembering things; and finding a simple, ideally as simple as possible, entry point.

    Of course it is not exactly the same as the rails-idiom shown here, since I'd also have to use:

        colours :green
        colours :disable
        colours false
    
    But I am also fine with set_colours :false. But in general I tend to prefer disable_colours in this case.

    Personally, since I know my brain is rather weak, I try to not use "cloaked" methods and just use oldschool setters and getters, where I treat set_foobar to be the same as foobar =.

    foobar= is a bit more elegant, but I also like set_xyz in general. Oddly enough I don't really use get_xyz; but I, to my shame, must admit that I like this:

       def return_base_directory
    
    Most will omit "return_", but I kind of like stupid code where I don't have to think. In particular in bigger projects.

    I don't really see a need for overloading methods though. I dislike having too many instance variables however had; I noticed that when I have like more than 10 @ variables, I often find it easier to just group them into a Hash instead, with Symbols as key. So for instance:

        @internal_hash[:use_colours] = false
    
    It's not that elegant compared to:

        @use_colours = false
    
    but I found a Hash to just be a lot more convenient to use here. And pp hash is super-userful. (We can easily get all instance variables programmatically, of course, but I still find a Hash structure so much more logical and convenient to use and read than many different instance variables.)
    • the_sleaze_

      default arguments are a great, but I tend to advise that we cap them at 1. Too high arity is a smell.

efficax

an "interesting trick" that is yet another demonstration that ruby is terrible language with too much magic

DataDaoDe

This reminded me of something I did almost two decades ago now that I feel really improved my ability to program in Ruby at the time. I spent months reading through ActiveSupport and Rails source code and re-implemented whole subsystems on my own to just understand how they worked. I had a blast and learned a ton along the way not just about ruby but about software engineering and being able to process and understand "large projects". At the time, I also remember really enjoying Jim Weirich's talks and his good-natured personality inspired me to dig into rake and rubygems as well.

Maledictus

Ruby is beautiful :'-)

semiquaver

Wow, I wrote Ruby for 15+ years and never saw this trick!

  • rubyfan

    Same and it’s really unclear to me why you would want this access pattern over. It seems like it might lead to unintended consequences.

koolba

What happens if you pass in (nothing_provided = true) as the value?

Does it return back the empty current value?

I’m no ruby expert, but seems like the freeze approach avoids that with a unique inaccessible object.

  • vidarh

    If you pass in (nothing_provided = true), the method received "true" as its argument, not the expression, so it acts exactly as if you pass in true.

  • XYen0n

    This expression returns true. It should be in a different scope from the default parameter value, so I assume it is equivalent to passing true directly.

thisismyopinion

Please fix the indentation of the code -_-

shevy-java

    def index_with(default = (no_default = true))
      if block_given?
        to_h { |elem| [elem, yield(elem)] } # rubocop:disable Rails/IndexWith
      elsif no_default
        to_enum(:index_with) { size if respond_to?(:size) }
      else
        to_h { |elem| [elem, default] } # rubocop:disable Rails/IndexWith
      end
    end
Who, other than the rather strange people in rails, write code like that?

It does not convey anything useful or meaningful. It is complicated to read and not easy to understand. Just that # comment there shows a lack of trust since it just appeases rubocop.

I have been critical of the rails people before, and this is another example. They don't really write ruby code. Sure, it is valid ruby code, but AI can write valid ruby code too and a monkey can as well if given enough time (and tries).

My criticism is not confined to that alone, though. Take the following:

    NOT_PROVIDED = Object.new.freeze
Again, this is just madness. I am noticing that rails people slap down .freeze onto everything. This. Is. Not. Ruby. You don't see matz doing that. It is an anti-pattern.

I understand WHY it originated, of course; a lot of this has to do with how strings were non-frozen in the past. Matz changed this eventually, but that .freeze pattern still remains deeply rooted in the brain of the rails people. They often come up with craziness, such as ActiveSupport::HashWithIndifferentAccess.

Again, I understand why (don't want to care about Strings or Symbols as keys); Jeremy wrote a rebuttal about this already, so I won't repeat it (he is spot on), but I think it is time to end the rails dominance in ruby in general. This is now, of course, much easier with DHH going all-in on AI, and the most sad rails conference of all times, where DHH declared how ruby on rails is de-facto dead (now it is all AI rust, baby).

Ruby really has a ton of problems. I'll not repeat them here all, but https://po-ru.com/2026/10/18/why-im-no-longer-updating-this-... summarized it nicely. With Claude being the new de-facto language designer, it may be best to completely re-think ruby. I do not see ruby having a future as agentic AI slop surrogate. It will just further accelerate decay against humans here, which is a problem other projects also suffer. You can find that on many comments - it is a real problem now. If you have two humans, and one claude slops all the time, and even uses claude to "interact" with other humans, you no longer communicate really. You kind of claude-cell isolated yourself.

I am not saying this is the case for all claude users, since some understand the problem domain - but many others do not understand that this is a real problem, which is shocking. Paul kind of understood the emerging problem here.

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection