Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Anonymous Block Forwarding in Ruby (writesoftwarewell.com)
27 points by thunderbong on Feb 15, 2024 | hide | past | favorite | 10 comments


Personally, I welcome our new anonymous block overlords. As a developer who writes more library code than app code, I think this is a good addition. Doing a cursory check on my code, in about 80% (gross estimation) of cases where a method captures a block, it just passes it on to another method call. The new style of anonymous block helps signify that the block is not directly manipulated or stored, but is just forwarded to another method. LGTM.


As a +10years Ruby dev, I don't see anything looking "pretty nice" about this, just yet another a new confusing way of achieving the same result, but differently.


I've been doing Ruby for some 15 years now and the major thing that puts me off is the community's love for implicitness.

This is another case: we had a way that requires a programmer to explicitly define what she is forwarding and where she is forwarding it to. And now we have a way that requires the reader of software to know the intricacies of the language in order to understand how the "magic" works.

I truly fail to see how this makes a language better.


As a non ruby dev... This "block" malarkey has always seen slightly deranged to me. You know what would be even nicer syntax? Proper higher order functions!

Haskellish syntax example:

    execute f = f "test response"

    perform = execute

    perform print


Your code is very limited. Blocks allow you to return any type of object or to have any kind of side effects, the result is not limited to be an IO monad. Also in Haskell you can't use variable number of arguments and the syntax is very different (curry by default of first argument), so no way to translate haskell style to ruby.


Your proposal ignores that Ruby blocks support `break`, `next` (continue), `return` and exceptions.


    def execute(f)
      f.call "test response"
    end

    perform = TOPLEVEL_BINDING.method(:execute)

    perform.call Kernel.method(:puts)


The use case for this would be that it doesn't reify the block IOW doesn't allocate a proc to wrap the block.

... but that optimisation has already been made† (and IIRC it is too for *args and **kwargs that just get forwarded to calls), so it mostly exists for consistency with anonymous * and ** and valueless keys, as well as documentation (making it explicit that the method accepts a block right from the signature). Here's the discussion: https://bugs.ruby-lang.org/issues/11256

I don't particularly like it given the style I like to use, but I can see how people using a certain different style would as their style would be more consistent and carry better intent.

Anyway the post linked from the OP has a more detailed rundown: https://zverok.space/blog/2023-11-24-syntax-sugar4-argument-...

https://bugs.ruby-lang.org/issues/14045


"Looks pretty nice"... Looks confusing to me. Seeing this code for the first time I think it would be hard to figure out what it means.


It is confusing every time you look at it.

It's nothing more than a piece of code that is defined somewhere but pasted in in another location.

It's a mess to debug.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: