Ah, indeed, there are subtle differences with lvars at the top-level in IRB vs 
in a method scope. Not sure if I'd consider this a bug or not, but to 
illustrate:

>> result = nil
=> nil
>> Dispatch::Queue.concurrent.sync do
>>   result = true
>> end
=> nil
>> result
=> true
>> def test
>>   result = nil
>>   Dispatch::Queue.concurrent.sync do
>>     result = true
>>   end
>>   result
>> end
=> nil
>> test
=> nil


Anyway, we're getting away from the original question. If you replace your 
lvars with ivars (s/result/@result/ above), then things will work. Just be 
careful of the possibility of concurrency bugs when assigning the same ivar 
from multiple queued blocks (and also have a look at the dispatch gem which has 
some convenience methods to make this sort of thing easier). 


On Saturday, October 22, 2011 at 6:30 AM, Michael Johnston wrote:

> Very strange, your example works for me in irb too. Irb must do something odd 
> with locals. Have you tried this outside of irb, though? If you wrap with a 
> method def'n in irb, it behaves differently, and the fact that locals are 
> copied has been discussed lots on the list. But Laurent (I think) said this 
> will likely change, has it already? I'm on 0.10
> 
> 
> 
> $ macirb --noprompt
> def check
>  print "can I change a local scalar? "
>  maybe = "nope"
>  $q.sync do
>  maybe = "yep"
>  end
>  puts maybe
> end
> => nil
> def check_p
>  print "can I assign to a pointer? "
>  maybe_p = Pointer.new(:id)
>  maybe_p.assign "nope"
>  $q.sync do
>  maybe_p.assign "yep"
>  end
>  puts maybe_p[0]
> end
> => nil
> def check_w
>  print "can I assign to a wrapper attr? "
>  maybe = ResultWrapper.new("nope")
>  $q.sync do
>  maybe.value = "yep"
>  end
>  puts maybe.value 
> end
> => nil
> ResultWrapper = Struct.new(:value)
> => ResultWrapper
> $q= Dispatch::Queue.new('q')
> => q
> check
> can I change a local scalar? nope
> => nil
> # but using a pointer works:
> => nil
> check_p
> can I assign to a pointer? yep
> => nil
> # or a wrapper (but more expensive for tight loops):
> => nil
> check_w
> can I assign to a wrapper attr? yep
> => nil
> $q= Dispatch::Queue.concurrent
> => com.apple.root.default-priority
> # double-checking it isn't different for the parallel queues:
> => nil
> check
> can I change a local scalar? nope
> => nil
> check_p
> can I assign to a pointer? yep
> => nil
> check_w
> can I assign to a wrapper attr? yep
> => nil
> 
> 
> 
> 
> 
> 
> 
> 
> 
> Cheerio,
> 
> Michael Johnston
> lastobe...@mac.com (mailto:lastobe...@mac.com)
> 
> 
> 
> 
> On 2011-10-22, at 12:32 AM, Joshua Ballanco wrote:
> 
> > On Saturday, October 22, 2011 at 1:35 AM, Michael Johnston wrote:
> > > When I need to get a queue-protected result into a local in code that is 
> > > concurrent (so I can't use an ivar) is a pointer the best (only) way to 
> > > get the result of a sync block? Assuming I don't want to factor out a 
> > > method object.
> > > 
> > > 
> > > ex:
> > > 
> > > result_p = Pointer.new(:id)
> > > some_queue.sync do
> > >  result_p.assign(value_protected_by_queue)
> > > end
> > > result = result_p[0]
> > > 
> > > it's not very ruby-ish...
> > 
> > There's no restriction on not using ivars in block. Indeed, even locals are 
> > in scope in a block (and with a #sync dispatched block such as the one you 
> > provided, there aren't even any threading issues):
> > 
> > result = nil
> > Dispatch::Queue.concurrent.sync do
> >  result = true
> > end
> > p result #=> true 
> > _______________________________________________
> > MacRuby-devel mailing list
> > MacRuby-devel@lists.macosforge.org 
> > (mailto:MacRuby-devel@lists.macosforge.org)
> > http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
> 
> _______________________________________________
> MacRuby-devel mailing list
> MacRuby-devel@lists.macosforge.org (mailto:MacRuby-devel@lists.macosforge.org)
> http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel

_______________________________________________
MacRuby-devel mailing list
MacRuby-devel@lists.macosforge.org
http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel

Reply via email to