Forum: Ruby Nilling for GC

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
01bb0d480d4d2777661a15165b842590?d=identicon&s=25 Paganoni (Guest)
on 2009-04-02 09:21
(Received via mailing list)
Hi, I've read that
http://whytheluckystiff.net/articles/theFullyUptur....
I have a background script that runs continuously and threads some tasks
on demand. I keep track of the launched tasks but, by keeping those
tracks, I certainly prevent tasks classes instances and threads
instances to be discarded by the garbage collector.

Data are stored like that :

@workers[:one_category] = []
@workers[:one_category] << {:started_at => Time.now, :thread => th}

So, I'm trying to setup a cleaner that would nil old references but I'm
lost in maps :

@semaphore.synchronize do
  @workers.map{|k,v| v.map{|worker| (Time.now - worker[:started_at] > 5
&& worker[:thread].status == false) ? (cleaned +=1; nil) : worker}}
end

When condition is true, cleaned is incremented but the nil does not
replace @workers entry.

So, I did another test :
hs = {}
hs[:toto] = []
hs[:toto] << {:kk => 28, :so => 'yes'}
hs[:toto] << {:kk => 30}
hs[:tata] = []
hs[:tata] << {:kk => 2}

hs = hs.map{|k,v| v.map {|a| a[:kk] > 28 ? nil : a} }
pp hs displays
[[{:kk=>28, :so=>"yes"}, nil], [{:kk=>2}]]

This one works right, for each hs entry, array is nilled if :kk value is
> to 28

Obviously there is a mistake somewhere in the first code source but I
don't find it.

Any help appreciated, thank you
8f6f95c4bd64d5f10dfddfdcd03c19d6?d=identicon&s=25 Rick Denatale (rdenatale)
on 2009-04-02 09:58
(Received via mailing list)
On Thu, Apr 2, 2009 at 3:19 AM, Paganoni <noway@fakenullvoid.com> wrote:

> @workers[:one_category] << {:started_at => Time.now, :thread => th}
> replace @workers entry.
> pp hs displays
> Any help appreciated, thank you
>

@workers.map{|k,v| v.map{|worker| (Time.now - worker[:started_at] > 5  #
...

vs.

hs = hs.map{|k,v| v.map {|a| a[:kk] > 28 ? nil : a} }

In the first case you create a new array from the nested map calls and
then
THROW IT AWAY, @workers still refers to the old array.

In the second you compute a new array and assign it to hs.

--
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale
Fa2521c6539342333de9f42502657e5a?d=identicon&s=25 Eleanor McHugh (Guest)
on 2009-04-02 10:28
(Received via mailing list)
On 2 Apr 2009, at 08:19, Paganoni wrote:
> @workers[:one_category] = []
> @workers[:one_category] << {:started_at => Time.now, :thread => th}
>
> So, I'm trying to setup a cleaner that would nil old references but
> I'm
> lost in maps :
>
> @semaphore.synchronize do
> @workers.map{|k,v| v.map{|worker| (Time.now - worker[:started_at] > 5
> && worker[:thread].status == false) ? (cleaned +=1; nil) : worker}}
> end

You could write something like:

  def thread_dead? worker
    (Time.now - worker[:started_at] > 5) && (worker[:thread].status ==
false)
  end

  @semaphore.synchronize do
    hs.delete_if do |k, v|
      v.map! { |worker| thread_dead?(worker) ? (cleaned += 1; nil) :
worker }.compact!
      v.empty?
    end
  end


Ellie

Eleanor McHugh
Games With Brains
http://slides.games-with-brains.net
----
raise ArgumentError unless @reality.responds_to? :reason
01bb0d480d4d2777661a15165b842590?d=identicon&s=25 Paganoni (Guest)
on 2009-04-02 16:05
(Received via mailing list)
le 02/04/2009 09:57, Rick DeNatale nous a dit:
>
> In the first case you create a new array from the nested map calls and then
> THROW IT AWAY, @workers still refers to the old array.
>
> In the second you compute a new array and assign it to hs.
>

But can I miss this sort of things for hours ???

Thanks !
01bb0d480d4d2777661a15165b842590?d=identicon&s=25 Paganoni (Guest)
on 2009-04-02 22:15
(Received via mailing list)
le 02/04/2009 10:27, Eleanor McHugh nous a dit:

>       v.map! { |worker| thread_dead?(worker) ? (cleaned += 1; nil) :
> worker }.compact!
>       v.empty?
>     end
>   end
>
>

Your delete_if solution is quite elegant because self explanatory !

Thanks
Fa2521c6539342333de9f42502657e5a?d=identicon&s=25 Eleanor McHugh (Guest)
on 2009-04-02 23:48
(Received via mailing list)
On 2 Apr 2009, at 21:14, Paganoni wrote:
>> worker }.compact!
>>       v.empty?
>>     end
>>   end
>
> Your delete_if solution is quite elegant because self explanatory !

Thank you :)

The delete_if could also be written as a one-liner, but it looks uglier:

  hs.delete_if { |k, v| (v.map! { |worker| thread_dead?(worker) ?
(cleaned += 1; nil) :  worker }.compact! || v).empty? }

It always bugs me that compact! returns nil if no changes occur,
rather than the enum as I seem to use this particular idiom a lot *sigh*


Ellie

Eleanor McHugh
Games With Brains
http://slides.games-with-brains.net
----
raise ArgumentError unless @reality.responds_to? :reason
770048af205ed307b8cf35ae2282ee2f?d=identicon&s=25 Michael Malone (Guest)
on 2009-04-02 23:54
(Received via mailing list)
> raise ArgumentError unless @reality.responds_to? :reason
>
>
>
Yes, I find it equally annoying that strip! has the same bahviour

=======================================================================
This email, including any attachments, is only for the intended
addressee.  It is subject to copyright, is confidential and may be
the subject of legal or other privilege, none of which is waived or
lost by reason of this transmission.
If the receiver is not the intended addressee, please accept our
apologies, notify us by return, delete all copies and perform no
other act on the email.
Unfortunately, we cannot warrant that the email has not been
 altered or corrupted during transmission.
=======================================================================
Ae16cb4f6d78e485b04ce1e821592ae5?d=identicon&s=25 Martin DeMello (Guest)
on 2009-04-02 23:56
(Received via mailing list)
On Fri, Apr 3, 2009 at 3:16 AM, Eleanor McHugh
<eleanor@games-with-brains.com> wrote:
>
> It always bugs me that compact! returns nil if no changes occur, rather than
> the enum as I seem to use this particular idiom a lot *sigh*

yeah, it seems like a very c-like thing to do :( i'd rather have it
set a (pseudo-)global variable the way regexp matches do.

martin
1bc63d01bd3fcccc36fb030a62039352?d=identicon&s=25 David Masover (Guest)
on 2009-04-03 01:14
(Received via mailing list)
On Thursday 02 April 2009 16:46:37 Eleanor McHugh wrote:

>   hs.delete_if { |k, v| (v.map! { |worker| thread_dead?(worker) ?
> (cleaned += 1; nil) :  worker }.compact! || v).empty? }
>
> It always bugs me that compact! returns nil if no changes occur,
> rather than the enum as I seem to use this particular idiom a lot *sigh*

It could also be written like this, if I understand it:

hs.delete_if { |k, v| (v.map! { |worker| thread_dead?(worker) ? (cleaned
+= 1;
nil) :  worker }.tap(&:compact!).empty? }

I don't feel strongly about compact! -- after all, it may be useful to
know
whether it found anything. But this is exactly what tap is for, right?

For those on 1.8.6:

class Object
  def tap
    yield self
    self
  end
end
Fa2521c6539342333de9f42502657e5a?d=identicon&s=25 Eleanor McHugh (Guest)
on 2009-04-03 02:24
(Received via mailing list)
On 3 Apr 2009, at 00:13, David Masover wrote:
>
> hs.delete_if { |k, v| (v.map! { |worker| thread_dead?(worker) ?
> (cleaned += 1;
> nil) :  worker }.tap(&:compact!).empty? }
>
> I don't feel strongly about compact! -- after all, it may be useful
> to know
> whether it found anything. But this is exactly what tap is for, right?

I've only just started moving over to 1.9 so I've not used tap(), I'll
bear it in mind for the future. To be honest though I can't recall a
single occasion where I've used compact!() that I didn't find the nil
result inconvenient and have even been known to redefine it to work
the way I prefer when it's been frequently used in a program :)


Ellie

Eleanor McHugh
Games With Brains
http://slides.games-with-brains.net
----
raise ArgumentError unless @reality.responds_to? :reason
This topic is locked and can not be replied to.