* [ruby-core:69208] [Ruby trunk - Bug #11156] [Open] Indeterminate Behavior for Curly-braced Blocks with Function Argument Missing Parenthesis
[not found] <redmine.issue-11156.20150515224930@ruby-lang.org>
@ 2015-05-15 22:49 ` 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
2 siblings, 0 replies; 4+ messages in thread
From: faraz.yashar @ 2015-05-15 22:49 UTC (permalink / raw
To: ruby-core
Issue #11156 has been reported by Faraz Yashar.
----------------------------------------
Bug #11156: Indeterminate Behavior for Curly-braced Blocks with Function Argument Missing Parenthesis
https://bugs.ruby-lang.org/issues/11156
* Author: Faraz Yashar
* Status: Open
* 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:
~~~
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.
~~~
example(1) { "block" }
# 1
# block
example 1 { "block" }
# SyntaxError: syntax error, unexpected '{', expecting end-of-input
~~~
Array literals, however, succeed:
~~~
example([1]) { "block" }
# 1
# block
example [1] { "block" }
# 1
# block
~~~
Identifiers are called as methods if parentheses are omitted:
~~~
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:
~~~
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...
~~~
example(Integer(1)) { "block" }
# 1
# block
example Integer(1) { "block" }
# 1
# no block
~~~
...except `Time.parse` gets weird:
~~~
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/
^ permalink raw reply [flat|nested] 4+ messages in thread
* [ruby-core:69210] [Ruby trunk - Bug #11156] [Rejected] Indeterminate Behavior for Curly-braced Blocks with Function Argument Missing Parenthesis
[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 ` nobu
2015-05-16 8:06 ` [ruby-core:69213] [Ruby trunk - Bug #11156] " faraz.yashar
2 siblings, 0 replies; 4+ messages in thread
From: nobu @ 2015-05-16 0:19 UTC (permalink / raw
To: ruby-core
Issue #11156 has been updated by Nobuyoshi Nakada.
Description updated
Status changed from Open to Rejected
What's your point?
`Time.parse` states as:
# If a block is given, the year described in +date+ is converted by the
# block. For example:
#
# Time.parse(...) {|y| 0 <= y && y < 100 ? (y >= 69 ? y + 1900 : y + 2000) : y}
----------------------------------------
Bug #11156: Indeterminate Behavior for Curly-braced Blocks with Function Argument Missing Parenthesis
https://bugs.ruby-lang.org/issues/11156#change-52464
* 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/
^ permalink raw reply [flat|nested] 4+ messages in thread
* [ruby-core:69213] [Ruby trunk - Bug #11156] Indeterminate Behavior for Curly-braced Blocks with Function Argument Missing Parenthesis
[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 ` faraz.yashar
2015-05-17 19:42 ` [ruby-core:69218] " Austin Ziegler
2 siblings, 1 reply; 4+ messages in thread
From: faraz.yashar @ 2015-05-16 8:06 UTC (permalink / raw
To: ruby-core
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/
^ permalink raw reply [flat|nested] 4+ messages in thread
* [ruby-core:69218] Re: [Ruby trunk - Bug #11156] Indeterminate Behavior for Curly-braced Blocks with Function Argument Missing Parenthesis
2015-05-16 8:06 ` [ruby-core:69213] [Ruby trunk - Bug #11156] " faraz.yashar
@ 2015-05-17 19:42 ` Austin Ziegler
0 siblings, 0 replies; 4+ messages in thread
From: Austin Ziegler @ 2015-05-17 19:42 UTC (permalink / raw
To: Ruby developers
[-- 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 --]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2015-05-17 19:27 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[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 ` [ruby-core:69218] " Austin Ziegler
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).