From: "drbrain (Eric Hodel)" Date: 2012-08-15T10:11:03+09:00 Subject: [ruby-core:47197] [ruby-trunk - Feature #6868] Make `do` in block syntax optional when the block is the last argument of a method and is not an optional argument Issue #6868 has been updated by drbrain (Eric Hodel). =begin It seems impossible to implement without fundamentally changing the feel of writing ruby. Due to enumerators, currently your example results in a SyntaxError: $ pbpaste | ruby20 -:7: syntax error, unexpected keyword_end, expecting $end How do we disambiguate between existing uses of (({&block})) and your proposal? Currently a method with (({&block})) accepts an optional block argument that is captured to the local variable (({block})). Since a named block argument is always optional it can be used by methods that return Enumerators (such as creating an enumerator from an Enumerable internal to the object). Changing this to mean "a block argument is required" breaks such usage. After solving the problem of specifying a method's signature to enable your special parsing, how do we look up this information at runtime if the method is dynamically defined or method_missing is involved? How do we parse this example? class C def method do_three_times puts "Hi" end end def initialize # defines the do_three_times method in a manner that enables "do"-less syntax require 'c/do_three_times' end end C.new.do_three_times The definition of (({do_three_times})) is ambiguous when the call is encountered, so the number of (({end}))s to consume is impossible to determine. Ruby can't look in (({c/do_three_times.rb})) to determine how to parse (({do_three_times})) since it is dynamic. If the parser assumes (({do_three_times})) is a do-less block then (({C.new})) will require (({c/do_three_times.rb})). However, if that file defines (({do_three_times})) to be a method that returns an Enumerator (not a do-less block) then the file was required at the wrong spot (as the second (({end})) after (({puts})) closed C and #initialize was not part of class C so the require should not have happened. I'm unsure how you are going to resolve ambiguity due to the dynamic nature of ruby absent a (({do})) or introduction of some other discriminator (such as python's significant whitespace). =end ---------------------------------------- Feature #6868: Make `do` in block syntax optional when the block is the last argument of a method and is not an optional argument https://bugs.ruby-lang.org/issues/6868#change-28875 Author: alexeymuranov (Alexey Muranov) Status: Feedback Priority: Normal Assignee: Category: core Target version: 3.0 =begin I propose to make the use of "(({do}))" in block syntax optional if the block is the last argument of a method and if it is a required argument, at least if the block does not take parameters. (I think this would be in line with how for example the last hash argument is treated.) I also think that this syntactic change may allow in future versions of Ruby to make (({def})), (({class})), (({module})) methods instead of keywords. Something like: 3.time puts "Hi!" end instead of 3.time do puts "Hi!" end I know this is not a good example, because for (({#times})) the block argument is optional. =end -- http://bugs.ruby-lang.org/