From: Rick DeNatale Date: 2007-09-21T02:38:22+09:00 Subject: Re: Ruby parser wierdness? On 9/20/07, Sharon Rosner wrote: > 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. -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/