Ruby parser wierdness?

S

Sharon Rosner

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
 
R

Rick DeNatale

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?

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.
 

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

Forum statistics

Threads
474,264
Messages
2,571,323
Members
48,008
Latest member
KieraMcGuf

Latest Threads

Top