Thread: super should be first line or last line?

C

christoforever

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?
 
S

Stefan Lang

2008/10/10 [email protected] said:
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?

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
 
C

christoforever

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?
 
P

Pit Capitain

2008/10/10 [email protected] said:
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
 
D

David A. Black

Hi --

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?

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

--
Rails training from David A. Black and Ruby Power and Light:
Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
Advancing with Rails January 19-22 Fort Lauderdale, FL *
* Co-taught with Patrick Ewing!
See http://www.rubypal.com for details and updates!
 
J

Joel VanderWerf

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?

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.)
 
B

Brian Candler

Christopher said:
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]
 
R

Robert Klemme

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
 
C

Charles Oliver Nutter

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?

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
 
C

christoforever

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?

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

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
 
R

Robert Klemme

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top