ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
From: Austin Ziegler <halostatue@gmail.com>
To: Ruby developers <ruby-core@ruby-lang.org>
Subject: [ruby-core:69218] Re: [Ruby trunk - Bug #11156] Indeterminate Behavior for Curly-braced Blocks with Function Argument Missing Parenthesis
Date: Sun, 17 May 2015 15:42:54 -0400	[thread overview]
Message-ID: <CAJ4ekQuDt72kgwytO9s36hv_TfUyPPqL6+hhQOk9NqDANt3H-w@mail.gmail.com> (raw)
In-Reply-To: <redmine.journal-52465.20150516080633.530b233318e36d3d@ruby-lang.org>

[-- Attachment #1: Type: text/plain, Size: 4319 bytes --]

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

[-- Attachment #2: Type: text/html, Size: 5882 bytes --]

      reply	other threads:[~2015-05-17 19:27 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <redmine.issue-11156.20150515224930@ruby-lang.org>
2015-05-15 22:49 ` [ruby-core:69208] [Ruby trunk - Bug #11156] [Open] Indeterminate Behavior for Curly-braced Blocks with Function Argument Missing Parenthesis faraz.yashar
2015-05-16  0:19 ` [ruby-core:69210] [Ruby trunk - Bug #11156] [Rejected] " nobu
2015-05-16  8:06 ` [ruby-core:69213] [Ruby trunk - Bug #11156] " faraz.yashar
2015-05-17 19:42   ` Austin Ziegler [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.ruby-lang.org/en/community/mailing-lists/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAJ4ekQuDt72kgwytO9s36hv_TfUyPPqL6+hhQOk9NqDANt3H-w@mail.gmail.com \
    --to=ruby-core@ruby-lang.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).