Ruby parser wierdness?

Hi gang

I’ve stumbled upon a weird phenomenon when trying nested Dataset#query
methods with Sequel:

ds = DB[:items].query do
select :x, :y
where :x => DB[:stuff].query do
select :a
where :b => DB[:misc].query do
select :c
where :d => true
end
end
end

#=> /usr/local/lib/ruby/gems/1.8/gems/sequel-0.2.0.2/lib/sequel/…/
sequel/dataset/convenience.rb:217:in `instance_eval’: block not
supplied (ArgumentError)

If I enclose the nested procs in parens everything works fine:

ds = DB[:items].query do
select :x, :y
where :x => (DB[:stuff].query do
select :a
where :b => (DB[:misc].query do
select :c
where :d => true
end)
end)
end

It also works if I use the curly brackets notation:

ds = DB[:items].query {
select :x, :y
where :x => DB[:stuff].query {
select :a
where :b => DB[:misc].query {
select :c
where :d => true
}
}
}

Is the error above the intended behavior? If it is, can someone
explain what’s going on?

best
Sharon

On 9/20/07, Sharon R. [email protected] wrote:

    select :c


}

}

Is the error above the intended behavior? If it is, can someone
explain what’s going on?

It’s a matter of the operator precedence of do and {}.

Braces bind more strongly than do (In general in Ruby symbols bind
tighter than keywords)

irb(main):001:0> def m1(arg)
irb(main):002:1> puts “m1 got block” if block_given?
irb(main):003:1> end
=> nil
irb(main):004:0> def m2
irb(main):005:1> puts “m2 got block” if block_given?
irb(main):006:1> end
=> nil
irb(main):007:0> m1 m2 {}
m2 got block
=> nil
irb(main):008:0> m1 m2 do;end
m1 got block
=> nil

So in the expression

where :x => DB[:stuff].query do;end

The block is being given to the where method instead of the query
method.


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs