Re: assert_raise question

def test_raise
assert_raise ArgumentError {raise ArgumentError.new(“basic argument issue”)}
end

Now there’s suddenly an Exception: undefined method ‘ArgumentError’…
I was more than a little surprised to discover that the parens make a
difference here? Can anyone explain to me why there’s a difference?

I believe that x y z is parsed as x(y(z)):

irb(main):013:0> puts ArgumentError
ArgumentError
=> nil
irb(main):014:0> puts ArgumentError 123
(irb):14: warning: parenthesize argument(s) for future version
NoMethodError: undefined method ArgumentError' for main:Object from (irb):14 from :0 irb(main):015:0> puts ArgumentError(123) NoMethodError: undefined methodArgumentError’ for main:Object
from (irb):15
from :0
irb(main):016:0>

and x y {block} is parsed as x(y() {block}), i.e. y is forced to be a
method
call as that’s the only meaningful thing next to a block.

irb(main):017:0> def Wibble(*args,&blk)
irb(main):018:1> puts “Args: #{args.inspect}”
irb(main):019:1> puts “With block” if blk
irb(main):020:1> end
=> nil
irb(main):021:0> puts Wibble { raise “hello” }
Args: []
With block
nil
=> nil
irb(main):022:0> puts Wibble Wibble { raise “hello” }
(irb):22: warning: parenthesize argument(s) for future version
Args: []
With block
Args: [nil]
nil
=> nil

There’s also the ambiguity between hash literal and block to consider:

irb(main):027:0> puts { :one => 2 }
SyntaxError: compile error
(irb):27: parse error, unexpected tASSOC, expecting ‘}’
puts { :one => 2 }
^
from (irb):27
from :0
irb(main):028:0> puts({ :one => 2 })
one2
=> nil
irb(main):029:0> puts 123, { :one => 2 }
123
one2
=> nil
irb(main):030:0> puts { raise }

=> nil
irb(main):031:0> puts :one => 2
one2
=> nil

B.

Brian C. wrote:

def test_raise
assert_raise ArgumentError {raise ArgumentError.new(“basic argument issue”)}
end

Now there’s suddenly an Exception: undefined method ‘ArgumentError’…
I was more than a little surprised to discover that the parens make a
difference here? Can anyone explain to me why there’s a difference?

I believe that x y z is parsed as x(y(z)):

irb(main):013:0> puts ArgumentError
ArgumentError
=> nil
irb(main):014:0> puts ArgumentError 123
(irb):14: warning: parenthesize argument(s) for future version
NoMethodError: undefined method ArgumentError' for main:Object from (irb):14 from :0 irb(main):015:0> puts ArgumentError(123) NoMethodError: undefined methodArgumentError’ for main:Object
from (irb):15
from :0
irb(main):016:0>

and x y {block} is parsed as x(y() {block}), i.e. y is forced to be a
method
call as that’s the only meaningful thing next to a block.

[snip]

Well, now that you explained it, it makes perfect sense! Thanks.

I guess in the future I’ll double-check a little more carefully that my
code is doing what I expect when I leave out parens.

Doug