BEGIN and END vs. blocks

I know that { ... } and do ... end have differente precedente. But,
using the latter, I got a syntax error. (I'm using version 1.8)

IMHO, because there's something implicit?

Regards

$ ruby
p 5 do end
p(5) { }
p 5 { }
-:2: syntax error
p 5 { }
      ^

{} blocks require parens if you have arguments other than the block.

···

On 12 Sep 2005, at 15:01, leonardo.pires@gmail.com wrote:

I know that { ... } and do ... end have differente precedente. But,
using the latter, I got a syntax error. (I'm using version 1.8)

IMHO, because there's something implicit?

--
Eric Hodel - drbrain@segment7.net - http://segment7.net
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04

I think that's partially true. The curly form has a higher precedence
then the do ... end one. So, I can code:

def foo(duh)
  duh
end

def goo
  puts yield
end

foo goo { 'bar' }

In this case, goo is a argument, right?

It's evaluated and the result is the argument to foo: your code is equivalent to this version

foo( goo() { 'bar' } )

Kind regards

    robert

···

leonardo.pires@gmail.com wrote:

I think that's partially true. The curly form has a higher precedence
then the do ... end one. So, I can code:

def foo(duh)
duh
end

def goo
puts yield
end

foo goo { 'bar' }

In this case, goo is a argument, right?

So where does precedence come in?

···

leonardo.pires@gmail.com wrote:

I think that's partially true. The curly form has a higher precedence
then the do ... end one. So, I can code:

def foo(duh)
  duh
end

def goo
  puts yield
end

foo goo { 'bar' }

In this case, goo is a argument, right?

--
Chris Game

If you're not part of the solution, you're part of the precipitate.

From PickAxe (2nd, ed. pg 341):

"Braces have a high precedence; do has a low precedence. If the method
invocation has
parameters that are not enclosed in parentheses, the brace form of a
block will bind to
the last parameter, not to the overall invocation. The do form will
bind to the invocation."

Since the there isn't parentheses, the braces bind to goo (a argument
to foo). Using the do form, a error is generated (but it's ok: you're
passing a block to foo).

I forgot to say what I want to know in my first email (sorry!) and
noticed this only now: why I can't use the do form with BEGIN or END?

END do
  puts 'wow'
end

It's invalid! Because there's something implicit?

foo goo { 'bar' }
foo goo do 'bar' end

The first is the same as:
     foo( goo(){ 'bar' } )
     foo( goo do 'bar' end )

The second is the same as:
     foo( goo ){ 'bar' }
     foo( goo ) do 'bar' end

def foo( *args )
     puts "foo args: #{args}"
     puts "foo block result: #{yield}" if block_given?
     "foo return value"
end

def goo( *args )
     puts "goo args: #{args}"
     puts "goo block result: #{yield}" if block_given?
     "goo return value"
end

foo goo { 'bar' }
puts '-' * 40
foo goo do 'bar' end

#=> goo args:
#=> goo block result: bar
#=> foo args: goo return value
#=> ----------------------------------------
#=> goo args:
#=> foo args: goo return value
#=> foo block result: bar

···

On Sep 13, 2005, at 5:06 AM, Chris Game wrote:

So where does precedence come in?

> I think that's partially true. The curly form has a higher precedence
> then the do ... end one. So, I can code:
>
> def foo(duh)
> duh
> end
>
> def goo
> puts yield
> end
>
> foo goo { 'bar' }
>
> In this case, goo is a argument, right?

So where does precedence come in?

Maybe this will help (this is Hal Fulton's reply to me from about a month
ago(August 19, 2005) (on the similar question):

<quote>
Re: Newbie question

···

On Tuesday 13 September 2005 07:06 am, Chris Game wrote:

leonardo.pires@gmail.com wrote:

From: Hal Fulton <hal9000@hypermetrics.com>
To: ruby-talk@ruby-lang.org (ruby-talk ML)
Date: Yesterday 11:13:45 pm (20050819)

Randy Kramer wrote:

I'm not clear on what binding tighter means, or to what--any further hints
appreciated.

=
What he means is, it's a matter of precedence.

Observe the examples:

   puts %w{cat bat rat}.map { |w| w.capitalize }

   puts %w{cat bat rat}.map do |w|
     w.capitalize
   end

They mean essentially the same as:

   puts(%w{cat bat rat}.map { |w| w.capitalize })

   puts(%w{cat bat rat}.map) do |w|
     w.capitalize
   end

In the second one, the map doesn't have a block associated with it --
the block is associated with the puts instead. The map with the
empty block effectively does nothing, and the puts never calls the
block given to it.
</quote>

Randy Kramer

I forgot to say what I want to know in my first email (sorry!) and
noticed this only now: why I can't use the do form with BEGIN or END?

END do
  puts 'wow'
end

It's invalid! Because there's something implicit?

It is required to use { }, from parse.y:

                 > klBEGIN
                     {
                         if (in_def || in_single) {
                             yyerror("BEGIN in method");
                         }
                         local_push(0);
                     }
                   '{' compstmt '}'
                     {
                         ruby_eval_tree_begin = block_append(ruby_eval_tree_begin,
                                                             NEW_PREEXE($4));
                         local_pop();
                         $$ = 0;
                     }
                 > klEND '{' compstmt '}'
                     {
                         if (in_def || in_single) {
                             rb_warn("END in method; use at_exit");
                         }

                         $$ = NEW_ITER(0, NEW_POSTEXE(), $3);
                     }

···

On 13 Sep 2005, at 04:26, leonardo.pires@gmail.com wrote:

--
Eric Hodel - drbrain@segment7.net - http://segment7.net
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04