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