These are well-established rules of precedence for blocks in Ruby for a
long time. As a Rubyist for the last thirteen years, changing this would
surprise me more. You may as well ask about precedence of mathematical
operators in general (because people *do* find that surprising across all
languages). If you want to use braces against a function, use parentheses
just as if you want to do addition before multiplication.

Note that using POLS/POLA in an argument is specious. The measure of
surprise is whether Matz is surprised by the behaviour. *Everyone* finds
Ruby surprising early on for various reasons.

-a

On Sat, May 16, 2015 at 4:06 AM, <faraz.yashar / gmail.com> wrote:

> Issue #11156 has been updated by Faraz Yashar.
>
>
> I'm trying to demonstrate that the syntax is very confusing and
> error-prone, especially given that `do ... end` blocks do not behave
> similarly due to precedence differences.
>
> Consider the `travel_to` time travel method given by Rails'
> `ActiveSupport::Testing::TimeHelpers`. One would naturally expect that the
> following two statements would behave equivalently...
>
> ~~~ruby
> travel_to Time.parse('2015-01-01 00:00:00 +0000') do
>  Time.now # => 2015-01-01 00:00:00 +0000
> end
>
> travel_to Time.parse('2014-01-01 00:00:00 +0000') {
>  Time.now # => 2015-05-16 03:52:24 -0400
> }
> ~~~
>
> ...but they don't because of precedence behaviors. To me, these
> differences violate the principle of least astonishment, and they cause
> more confusion and open room for errors.
>
> ----------------------------------------
> Bug #11156: Indeterminate Behavior for Curly-braced Blocks with Function
> Argument Missing Parenthesis
> https://bugs.ruby-lang.org/issues/11156#change-52465
>
> * Author: Faraz Yashar
> * Status: Rejected
> * Priority: Normal
> * Assignee:
> * ruby -v: ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
> * Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN
> ----------------------------------------
> Given a function that takes an argument and a block, the behavior wildly
> varies when parenthesis are omitted from the functions argument.
>
> Consider the following function:
>
> ~~~ruby
> require 'time'
>
> def example(arg)
>   puts arg
>   if block_given?
>     puts yield
>   else
>     puts "no block"
>   end
> end
> ~~~
>
> Each of the following example sets presents one `example` call with
> parentheses explicitly defined and one whether the parenthesis are omitted.
>
> For most literals (e.g. 1, 'string', true, false, nil, %w[array]), missing
> parenthesis causes a syntax error.
>
> ~~~ruby
> example(1) { "block" }
> # 1
> # block
> example 1 { "block" }
> # SyntaxError: syntax error, unexpected '{', expecting end-of-input
> ~~~
>
> Array literals, however, succeed:
>
> ~~~ruby
> example([1]) { "block" }
> # 1
> # block
> example [1] { "block" }
> # 1
> # block
> ~~~
>
> Identifiers are called as methods if parentheses are omitted:
>
> ~~~ruby
> example(Time) { "block "}
> # Time
> # block
> example Time { "block" }
> # NoMethodError: undefined method `Time' for main:Object
>
> a = 1
> example(a) { "block" }
> # 1
> # block
> example a { "block" }
> # NoMethodError: undefined method `a' for main:Object
> ~~~
>
> Object with method calls simply skip the block when no parenthesis are
> present:
>
> ~~~ruby
> example(Time.now) { "block" }
> # 2015-05-15 18:16:50 -0400
> # block
> example Time.now { "block" }
> # 2015-05-15 18:16:50 -0400
> # no block
> ~~~
>
> Method calls with arguments behave about the same as the above...
>
> ~~~ruby
> example(Integer(1)) { "block" }
> # 1
> # block
> example Integer(1) { "block" }
> # 1
> # no block
> ~~~
>
> ...except `Time.parse` gets weird:
>
> ~~~ruby
> example(Time.parse('2015-01-01 0:00:00+00:00')) { "block" }
> # 2015-01-01 00:00:00 +0000
> # block
> # => nil
> example Time.parse('2015-01-01 0:00:00+00:00') { "block" }
> # 0000-01-01 00:00:00 +0000  <---- Year 2000?!
> # no block
> # => nil
> ~~~
>
> The lack of consistency across these use cases is extremely confusing and
> misleading. I'm of the opinion that parentheses omission should, in all
> cases, lead to a syntax error.
>
>
>
>
> --
> https://bugs.ruby-lang.org/
>



-- 
Austin Ziegler * halostatue / gmail.com * austin / halostatue.ca
http://www.halostatue.ca/ * http://twitter.com/halostatue