[MacRuby-devel] locals & dispatch: is using a pointer the best practice?

Joshua Ballanco jballanc at gmail.com
Sat Oct 22 21:27:50 PDT 2011


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
> lastobelus at mac.com (mailto:lastobelus at 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 at lists.macosforge.org (mailto:MacRuby-devel at lists.macosforge.org)
> > http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
> 
> _______________________________________________
> MacRuby-devel mailing list
> MacRuby-devel at lists.macosforge.org (mailto:MacRuby-devel at lists.macosforge.org)
> http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-devel/attachments/20111023/4f4f6b6e/attachment.html>


More information about the MacRuby-devel mailing list