From: Myron@..., Marston@... Date: 2014-01-13T00:05:25+00:00 Subject: [ruby-core:59722] [ruby-trunk - Bug #9397] Lambda#=== raises `ArgumentError` if the lambda accepts 0 args or requires more than 1 Issue #9397 has been updated by Myron Marston. Benoit Daloze wrote: > > Consider that ruby's syntax doesn't even allow you to call === with 0 or more than 1 argument unless you resort to hacks like send > > The syntax allows it, you just need a dot: > -> a, b { a + b }.=== 1,2 > -> a, b { a + b }.===(1,2) > -> { 42 }.=== > -> { 42 }.===() Interesting. You learn something new everyday :). I'd still put this in the category of hacks like `send`, though: the normal, idiomatic way of calling operator methods in ruby is to not use a dot. When was the last time you used a dot to send a message like `+`, `-`, `==`, `===`, `*`, etc? ---------------------------------------- Bug #9397: Lambda#=== raises `ArgumentError` if the lambda accepts 0 args or requires more than 1 https://bugs.ruby-lang.org/issues/9397#change-44236 * Author: Myron Marston * Status: Rejected * Priority: Normal * Assignee: * Category: * Target version: * ruby -v: 1.9+ * Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN, 2.1: UNKNOWN ---------------------------------------- Ruby 1.9 introduced `===` on lambdas/procs so that you can put them in case statements. I'm a fan of this, but there's an unfortunate side effect I've run into recently. If you have a lambda that accepts 0 args (e.g. `lambda { }`) or requires more than 1 arg (e.g. `lambda { |x, y| }`), calling `===` on it will raise an `ArgumentError`. I understand why: lambdas are strict about the number of arguments, and `===` is just an alias of `call` now. However, this makes things difficult in a gem when you want to use `===` to match arbitrary objects (since it's the general-purpose protocol ruby provides for that purpose) and there may be lambdas provided by the user. I ran into this in RSpec recently, and my (hacky) solution is to `rescue ArgumentError`: https://github.com/rspec/rspec-support/commit/caf76c5de26ea1ca93f09f1097a0092ee4bf828d It would be nice not to have to do this, and IMO, `===` on all built-in types should maintain the contract that they can be called with 1 arg and will not raise an error. Consider that ruby's syntax doesn't even allow you to call `===` with 0 or more than 1 argument unless you resort to hacks like `send` (e.g. `obj.send(:===, x, y, z)`). Given that, I think that `===` on lambdas should return false rather than raising an ArgumentError if the lambda does not support being called with 1 argument. -- http://bugs.ruby-lang.org/