Block Syntax Error

N

newbie

Hi,
Please see the following code
===>8=======================
def func *args,&blk
puts *args
instance_eval &blk
end

func("a str") {puts "blk"} #OK
func "a str" do puts "blk" end #OK

func "a str" {puts "blk"} #Sytax Error!?
===>8=======================

The last call give a syntax error, which part confuse ruby?
 
H

Hal Fulton

newbie said:
Hi,
Please see the following code
===>8=======================
def func *args,&blk
puts *args
instance_eval &blk
end

func("a str") {puts "blk"} #OK
func "a str" do puts "blk" end #OK

func "a str" {puts "blk"} #Sytax Error!?
===>8=======================

The last call give a syntax error, which part confuse ruby?

In my personal opinion, this is one of those things that
"should" work. But the Ruby parser is very complex. (Just
ask anyone who has tried to write another one.)

I am not sure exactly what is happening here, but I would
tend to think it is a side effect of the way the yacc
grammar is written.


Hal
 
C

Christophe Grandsire

Selon newbie said:
Hi,
Please see the following code
=3D=3D=3D>8=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D
def func *args,&blk
puts *args
instance_eval &blk
end

func("a str") {puts "blk"} #OK
func "a str" do puts "blk" end #OK

func "a str" {puts "blk"} #Sytax Error!?
=3D=3D=3D>8=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D

The last call give a syntax error, which part confuse ruby?

I wonder if it has to do with precedence rules. The different block synta=
xes
have different precendence rules, with {} binding more strongly than do..=
end.
{} only binds to the last expression, while do... end binds to the whole
expression. In other words, when you write:

func "a str" do puts "blk" end

Ruby sees:

func("a str") do puts "blk" end

(you may also think of it as: '(func "a str") do puts "blk" end', which
emphasises the precedence, although I don't know if it is correct Ruby sy=
ntax)

However, when you write:

func "a str" {puts "blk"}

Ruby sees:

func("a str" {puts "blk"})

The binding is tighter, and results in a syntax error since a string can'=
t take
a block.

I don't know why the two block syntaxes have different precedence, but I =
take it
there's a reason (just like there's a reason for the existence of "and" a=
nd
""&&" with identical meanings but different precedences).
--
Christophe Grandsire.

http://rainbow.conlang.free.fr

It takes a straight mind to create a twisted conlang.
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: Block Syntax Error"

|func "a str" {puts "blk"} #Sytax Error!?

Since

func foo {puts "blk"}

is parsed as

func(foo{puts "blk"})

then I think

func "a str" {puts "blk"}

should be parsed as

func("a str"{puts "blk"})

which is not a valid syntax.

matz.
 
D

David A. Black

Hi --

Hi,
Please see the following code
===>8=======================
def func *args,&blk
puts *args
instance_eval &blk
end

func("a str") {puts "blk"} #OK
func "a str" do puts "blk" end #OK

func "a str" {puts "blk"} #Sytax Error!?
===>8=======================

The last call give a syntax error, which part confuse ruby?

See other answers. I just want to put in a plug (since you're still a
nuby :) for using parentheses, especially in method definitions:

def func(*args, &blk)

I know it looks sort of cool without them, but I find (and I'm pretty
sure I'm far from the only one) that I have more trouble parsing it
visually, especially when you get things like:

def a b, c = 100

which is legal but, to my eye, too thin on visual cues.


David
 
J

J. Merrill

zhimin.wen said:
===>8=======================
def func *args,&blk
puts *args
instance_eval &blk
end

func("a str") {puts "blk"} #OK
func "a str" do puts "blk" end #OK

func "a str" {puts "blk"} #Sytax Error!?
===>8=======================

The last call give a syntax error, which part confuse ruby?

My opinion is that you should _want_ to put a comma before the {puts
"blk"} to make it clear that you are passing a block parameter to func,
rather than to "a str". Suppose the line were
func foo {puts "blk"}
where foo is a method -- in that case, the block is being passed to foo
(and the result of foo is being passed to func), and if you're passing
the block to func you'd write
func foo, {puts "blk"}

There are disadvantages to many attempts to reduce keystrokes, IMO.
 
D

David A. Black

Hi --

My opinion is that you should _want_ to put a comma before the {puts
"blk"} to make it clear that you are passing a block parameter to func,
rather than to "a str". Suppose the line were
func foo {puts "blk"}
where foo is a method -- in that case, the block is being passed to foo
(and the result of foo is being passed to func), and if you're passing
the block to func you'd write
func foo, {puts "blk"}

There's never a comma before a code block. You'd want to do:

func(foo) { puts "blk" }

to pass both the argument and the block to func.


David
 
H

Hal Fulton

Yukihiro said:
Hi,

In message "Re: Block Syntax Error"

|func "a str" {puts "blk"} #Sytax Error!?

Since

func foo {puts "blk"}

is parsed as

func(foo{puts "blk"})

then I think

func "a str" {puts "blk"}

should be parsed as

func("a str"{puts "blk"})

which is not a valid syntax.

OK, this makes sense. I should withdraw my previous comments then.


Hal
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,197
Messages
2,571,038
Members
47,633
Latest member
BriannaLyk

Latest Threads

Top