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/