Forum: Ruby Thread: super should be first line or last line?

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.
Christopher D. (Guest)
on 2008-10-10 17:05
(Received via mailing list)
While playing around with ruby threads I noticed that if you dont call
super when subclassing a thread you will get an initialization error.
So ok we throw a super in the initialize method and that clears things
up. Unfortunately if you put super as the first line in the initialize
method the rest of the initialize will not execute but the block which
is part of the initial thread creation gets initialized. However if
you put super as the last statement in the initialize method, the
whole initialize gets executed and then the block from the thread
creation gets executed. Does anyone else find this a bit funny? And
what is a good practice when subclassing thread... to put super first
or last statement in the initialize method? and is there any benefit
for either?
Stefan L. (Guest)
on 2008-10-10 17:45
(Received via mailing list)
2008/10/10 removed_email_address@domain.invalid 
<removed_email_address@domain.invalid>:
> or last statement in the initialize method? and is there any benefit
> for either?

Sorry, I haven't a direct answer. Do you have a good reason to
subclass Thread? There's probably a better way to achieve what
you want without subclassing.

Stefan
Christopher D. (Guest)
on 2008-10-10 18:21
(Received via mailing list)
On Oct 10, 9:43 am, Stefan L. <removed_email_address@domain.invalid>
wrote:
> > creation gets executed. Does anyone else find this a bit funny? And
> > what is a good practice when subclassing thread... to put super first
> > or last statement in the initialize method? and is there any benefit
> > for either?
>
> Sorry, I haven't a direct answer. Do you have a good reason to
> subclass Thread? There's probably a better way to achieve what
> you want without subclassing.
>
> Stefan

I've simply worked around the problem. I wanted the subclassed thread
simply to hold much more personal info( if you will ) related to that
particular's threads behavior/action with in the environment its
running. There are many of threads going at any one time, and the info
within each one is both different and needed for each. By putting
super at the bottom of the initialize method i've solved the problem I
just thought it was a bit funny that if I put super at the top the
block associated with the creation of the thread gets called first and
then the rest of the initialize method runs. I guess I've just been
treated so kindly with java threads that doing things a bit
differently ( in terms of threads) through me for a loop. However I
still believe this is a bad design decision on behalf of thread
creation with ruby. Seemingly no matter what the initialize method
(imho) should be executed first ..... though as im writing this Im now
thinking there is reason to have both. I suppose there could be
reasons to have the block called first and then initialize the thread
just as well as there are reasons to have the thread be initialized
first and then call the corresponding block. Anyone have any opinions
on the subject?
Pit C. (Guest)
on 2008-10-10 19:07
(Received via mailing list)
2008/10/10 removed_email_address@domain.invalid 
<removed_email_address@domain.invalid>:
> However I
> still believe this is a bad design decision on behalf of thread
> creation with ruby. ... Anyone have any opinions
> on the subject?

There's nothing special going on. If you override a method in a
subclass, the original method is called if and only if you call super.
It would be a *very* bad design decision to deviate from this simple
and clear principal.

The task of the original Thread#initialize method is to spawn a new
thread and call the given block in the new thread. If you override the
#initialize method in your subclass and don't call super, then no new
thread is created (who should do this and when ???). So it's your
responsibility to invoke the original method when it's appropriate for
your subclass. Since you obviously want to initialize some instance
variables before spawning the new thread, you should call super after
the initialization of your instance variables. If you want to do
something after spawning the new thread, you would put this code after
the call to super. As I said: there's nothing special with class
Thread. It behaves as every other class in Ruby.

Regards,
Pit
David A. Black (Guest)
on 2008-10-10 19:35
(Received via mailing list)
Hi --

On Fri, 10 Oct 2008, removed_email_address@domain.invalid wrote:

> or last statement in the initialize method? and is there any benefit
> for either?

I assume it's just how Thread#initialize is defined. If it yields to
the block, and you call it, then it will yield to the block. It's like
this:

   class C
     def initialize
       yield
     end
   end

   class D < C
     def initialize
       super
       puts "Back from calling super"
     end
   end

   D.new { puts "Inside block" }

Output:

   Inside block
   Back from calling super

It's just executing commands in the order you issue them.


David
Joel VanderWerf (Guest)
on 2008-10-10 21:21
(Received via mailing list)
removed_email_address@domain.invalid wrote:
> or last statement in the initialize method? and is there any benefit
> for either?

You can pass a block to super, and also yield within that block:

class MyThread < Thread
   def initialize(*args)
     puts "my init before super; Thread.current = #{Thread.current}"
     super do
       yield(*args)
       puts "my init in super; Thread.current = #{Thread.current}"
     end
     puts "my init after super; Thread.current = #{Thread.current}"
   end
end

th = MyThread.new do
   puts "in block"
end

th.join

__END__

Output:

my init before super; Thread.current = #<Thread:0xb7dd4700>
in block
my init in super; Thread.current = #<MyThread:0xb7cd4288>
my init after super; Thread.current = #<Thread:0xb7dd4700>

(Note that the current thread is different for methods called within the
block.)
Brian C. (Guest)
on 2008-10-10 23:17
Christopher Dancy wrote:
> I've simply worked around the problem. I wanted the subclassed thread
> simply to hold much more personal info( if you will ) related to that
> particular's threads behavior/action with in the environment its
> running. There are many of threads going at any one time, and the info
> within each one is both different and needed for each.

Another option to consider is using thread-local variables, rather than
instance variables in the thread object itself.

t = Thread.new {
  Thread.current[:foo] = "bar"
}
t.join
puts t[:foo]
Robert K. (Guest)
on 2008-10-11 01:37
(Received via mailing list)
On 10.10.2008 15:02, removed_email_address@domain.invalid wrote:
> While playing around with ruby threads I noticed that if you dont call
> super when subclassing a thread you will get an initialization error.
> So ok we throw a super in the initialize method and that clears things
> up. Unfortunately if you put super as the first line in the initialize
> method the rest of the initialize will not execute but the block which
> is part of the initial thread creation gets initialized.

This is wrong.

irb(main):001:0> class T < Thread
irb(main):002:1> def initialize
irb(main):003:2> p self
irb(main):004:2> super
irb(main):005:2> p self
irb(main):006:2> end
irb(main):007:1> end

irb(main):009:0> T.new { sleep 1; p self }.join
#<T:0x7ff78b48 run>
#<T:0x7ff78b48 sleep>
main
=> #<T:0x7ff78b48 dead>
irb(main):010:0>

The code in the block gets executed.  But the thread is started from
super so the thread is already running when the rest of initialize is
executed.  One more reason why it is a bad idea to inherit Thread.

If you need to store information in the thread you can always use
Thread.current[:key] = value

> However if
> you put super as the last statement in the initialize method, the
> whole initialize gets executed and then the block from the thread
> creation gets executed. Does anyone else find this a bit funny? And
> what is a good practice when subclassing thread... to put super first
> or last statement in the initialize method? and is there any benefit
> for either?

See above.  If you need to do complex calculations you should rather
create a class that does the work and stores all necessary information.

Regards

  robert
Charles Oliver N. (Guest)
on 2008-10-11 02:22
(Received via mailing list)
removed_email_address@domain.invalid wrote:
> or last statement in the initialize method? and is there any benefit
> for either?

I'll echo others' concerns about why you're doing this, but if the
initialize chain causes you headaches you could always redefine new for
your class:

class MyThread < Thread
   def self.new(arg1, arg2)
     super {
       Thread.current[:arg1] = arg1
       Thread.current[:arg2] = arg2
       yield
     }
   }
}

It would probably be better put in a separate data structure that spins
up a Thread internally though.

- Charlie
Christopher D. (Guest)
on 2008-10-11 06:10
(Received via mailing list)
On Oct 10, 6:19 pm, Charles Oliver N. <removed_email_address@domain.invalid>
wrote:
> > what is a good practice when subclassing thread... to put super first
>        Thread.current[:arg1] = arg1
> - Charlie
Thank you to everyone who has responded and for your insight. Coming
from a java threading background I simply assumed that creating a new
sub-classed thread would run the constructor and then the following
run method. Thank you for the comments however they are much
appreciated and allowed me to see a different point of view.

Sincerely,
Chris Dancy
Robert K. (Guest)
on 2008-10-11 11:01
(Received via mailing list)
On 11.10.2008 04:07, removed_email_address@domain.invalid wrote:

> Thank you to everyone who has responded and for your insight. Coming
> from a java threading background I simply assumed that creating a new
> sub-classed thread would run the constructor and then the following
> run method.

There is no run method in Ruby's threads.

> Thank you for the comments however they are much
> appreciated and allowed me to see a different point of view.

You're welcome.

Kind regards

  robert
This topic is locked and can not be replied to.