Using a Class (not an instance) into threads

Hi, i'm using Ragel parser generating Ruby code. The generated code
uses a Class instead of an instance, and that class has lots of
attributes and methods. Something like:

···

--------------
class MyParser

    class << self
        attr_accessor :_machine_trans_keys
        private :_machine_trans_keys, :_machine_trans_keys=
    end

  self._machine_trans_keys = [
        0, 0, 9, 34, 10, 10,
        9, 32, 9, 34, -64,
        126, -128, -65, -128, -65,
        -128, -65, -128, -65, -128, -65,
        10, 10, 9, 32, 13,
        13, 10, 10, 0, 127,
        0, 0, 0
    ]

  ...
  ...

  def self.run_machine(data)
      ...
  end

end
-------------

So I wonder how could I use this class into a threaded program. AFAIK
a singleton class is the Class itself, so if a running thread modifies
some singleton attribute then all the other threads will see that
change (error!!!).

Am I right? How could I achieve it?

Thanks a lot.

--
Iñaki Baz Castillo
<ibc@aliax.net>

Iñaki Baz Castillo wrote:

So I wonder how could I use this class into a threaded program. AFAIK
a singleton class is the Class itself, so if a running thread modifies
some singleton attribute then all the other threads will see that
change (error!!!).

Am I right? How could I achieve it?

This is not an example of a "singleton class". It is merely a class
with static methods which means that you don't have to make an instance
prior to using it. If the class that Ragel populated has no state
(which I don't believe it does) then it can safely be used in a threaded
context.

If you need further examples, please check out all the class level
methods in Math

···

=================================================================
As for "singleton class", The class is not the object itself as you
stated, but a class created solely for that instance.

class Foo
end

f = Foo.new
def f.poo
1
end

f.class <== Foo
f.poo <=== 1
Foo.new.poo <== undefined method!

--
Posted via http://www.ruby-forum.com/\.

This is not an example of a "singleton class". It is merely a class
with static methods which means that you don't have to make an instance
prior to using it.

Thanks for pointing it out.
When defining an attribute into "class << self [..] end" it means that
it is an instance attribute of the class (since in Ruby a Class is
also an instance). I though that *this* was called "Singleton".

If the class that Ragel populated has no state
(which I don't believe it does) then it can safely be used in a threaded
context.

During a method into MyParser class, there are *a lot* of attributes
whose value change, and that value is important to remain when the
function ends, so I understand that the class that Ragel populated
does have state, am I wrong?

If you need further examples, please check out all the class level
methods in Math

ok, I'll do.

=================================================================
As for "singleton class", The class is not the object itself as you
stated, but a class created solely for that instance.

class Foo
end

f = Foo.new
def f.poo
1
end

f.class <== Foo
f.poo <=== 1
Foo.new.poo <== undefined method!

I was wrong, thanks for clarifing :slight_smile:

···

2009/2/4 Ilan Berci <coder68@yahoo.com>:

--
Iñaki Baz Castillo
<ibc@aliax.net>

Math is a module and its methods are written as Ruby C extensions. Is
there any other example? :slight_smile:

···

2009/2/4 Ilan Berci <coder68@yahoo.com>:

If you need further examples, please check out all the class level
methods in Math

--
Iñaki Baz Castillo
<ibc@aliax.net>

This is not an example of a "singleton class". It is merely a class
with static methods which means that you don't have to make an instance
prior to using it.

Actually there is no such thing as a "static method". This term
belongs to Java, C++ and probably other languages. The attribute was
defined on the singleton class of instance MyParser which happens to
be a class.

So, Inaki, yes this state does only exist once and if you change it
concurrently you're in trouble.

Thanks for pointing it out.
When defining an attribute into "class << self [..] end" it means that
it is an instance attribute of the class (since in Ruby a Class is
also an instance). I though that *this* was called "Singleton".

"Singleton" is a general term denoting things where you have only one
from. A "Singleton Class" in Ruby is the class which you obtain when
doing

class <<any_object
  p self # inspects singleton class
end

This does exist for every instance - regular ones as well as classes,
since classes are objects as well.

If the class that Ragel populated has no state
(which I don't believe it does) then it can safely be used in a threaded
context.

During a method into MyParser class, there are *a lot* of attributes
whose value change, and that value is important to remain when the
function ends, so I understand that the class that Ragel populated
does have state, am I wrong?

I do not know Ragel but it may well be that the class that Ragel
created has only immutable state necessary for the parser and that the
parsing related state is in instances of that class. Can you post
more of MyParser?

Cheers

robert

···

2009/2/4 Iñaki Baz Castillo <ibc@aliax.net>:

2009/2/4 Ilan Berci <coder68@yahoo.com>:

--
remember.guy do |as, often| as.you_can - without end

There is no usage of class instances, but just class methods and class
attributes.

I attatch a Ragel generated Ruby parser (it's just a few extract of a SIP
parser I'm building).
Note that the Ragel generated code is from line 11 up to line 170.

Thanks a lot.

parser.rb (3.39 KB)

···

El Miércoles, 4 de Febrero de 2009, Robert Klemme escribió:

I do not know Ragel but it may well be that the class that Ragel
created has only immutable state necessary for the parser and that the
parsing related state is in instances of that class. Can you post
more of MyParser?

--
Iñaki Baz Castillo

Robert Klemme wrote:

This is not an example of a "singleton class". It is merely a class
with static methods which means that you don't have to make an instance
prior to using it.

Actually there is no such thing as a "static method". This term
belongs to Java, C++ and probably other languages. The attribute was
defined on the singleton class of instance MyParser which happens to
be a class.

robert

Yes.. sorry about "static" getting in there.. I come from C++ and my
terminology still sometimes gets messed up..

Please change to: "It's merely a class with class level methods...

ilan

···

--
Posted via http://www.ruby-forum.com/\.

I did not look too closely but it seems that the shared state is used
read only. You can easily verify yourself by simply freezing it and
see whether you get errors from that.

Cheers

robert

···

2009/2/4 Iñaki Baz Castillo <ibc@aliax.net>:

El Miércoles, 4 de Febrero de 2009, Robert Klemme escribió:

I do not know Ragel but it may well be that the class that Ragel
created has only immutable state necessary for the parser and that the
parsing related state is in instances of that class. Can you post
more of MyParser?

There is no usage of class instances, but just class methods and class
attributes.

I attatch a Ragel generated Ruby parser (it's just a few extract of a SIP
parser I'm building).
Note that the Ragel generated code is from line 11 up to line 170.

--
remember.guy do |as, often| as.you_can - without end

You are right! The only writtable variables are local variables inside class
methods!

Really thanks a lot for pointing it out :slight_smile:

···

El Miércoles, 4 de Febrero de 2009, Robert Klemme escribió:

2009/2/4 Iñaki Baz Castillo <ibc@aliax.net>:
> El Miércoles, 4 de Febrero de 2009, Robert Klemme escribió:
>> I do not know Ragel but it may well be that the class that Ragel
>> created has only immutable state necessary for the parser and that the
>> parsing related state is in instances of that class. Can you post
>> more of MyParser?
>
> There is no usage of class instances, but just class methods and class
> attributes.
>
> I attatch a Ragel generated Ruby parser (it's just a few extract of a SIP
> parser I'm building).
> Note that the Ragel generated code is from line 11 up to line 170.

I did not look too closely but it seems that the shared state is used
read only. You can easily verify yourself by simply freezing it and
see whether you get errors from that.

--
Iñaki Baz Castillo

Also, using a Class instead of instances is faster since there is no
need of "initialize" for each usage, am I right?

···

2009/2/4 Iñaki Baz Castillo <ibc@aliax.net>:

I did not look too closely but it seems that the shared state is used
read only. You can easily verify yourself by simply freezing it and
see whether you get errors from that.

You are right! The only writtable variables are local variables inside class
methods!

--
Iñaki Baz Castillo
<ibc@aliax.net>

In theory yes. But IMHO the primary reason for stuffing something into
the class should not be performance but the appropriateness in terms
of design. If it is something that all class instances must share it
belongs into the class.

Kind regards

robert

···

2009/2/5 Iñaki Baz Castillo <ibc@aliax.net>:

2009/2/4 Iñaki Baz Castillo <ibc@aliax.net>:

I did not look too closely but it seems that the shared state is used
read only. You can easily verify yourself by simply freezing it and
see whether you get errors from that.

You are right! The only writtable variables are local variables inside class
methods!

Also, using a Class instead of instances is faster since there is no
need of "initialize" for each usage, am I right?

--
remember.guy do |as, often| as.you_can - without end

* Iñaki Baz Castillo <ibc@aliax.net> (14:44) schrieb:

···

2009/2/4 Iñaki Baz Castillo <ibc@aliax.net>:

I did not look too closely but it seems that the shared state is used
read only. You can easily verify yourself by simply freezing it and
see whether you get errors from that.

You are right! The only writtable variables are local variables inside class
methods!

Also, using a Class instead of instances is faster since there is no
need of "initialize" for each usage, am I right?

I don't quite understand that question. Classes are instances, too. And
objects without state don't need an initialize method.

mfg, simon .... l

Think when he said shared state he actually meant shared code. Maybe not.

Blog: http://random8.zenunit.com/
Learn rails: http://sensei.zenunit.com/

···

On 06/02/2009, at 5:34 PM, Simon Krahnke <overlord@gmx.li> wrote:

* Iñaki Baz Castillo <ibc@aliax.net> (14:44) schrieb:

2009/2/4 Iñaki Baz Castillo <ibc@aliax.net>:

I did not look too closely but it seems that the shared state is used
read only. You can easily verify yourself by simply freezing it and
see whether you get errors from that.

You are right! The only writtable variables are local variables inside class
methods!

Also, using a Class instead of instances is faster since there is no
need of "initialize" for each usage, am I right?

I don't quite understand that question. Classes are instances, too. And
objects without state don't need an initialize method.

mfg, simon .... l

Exactly, but in my case, if I'd use objects then I would need
"initiate" method, so in my particular case it is faster to use a
Class. Note that the Class code is initiated during class loading,
since it's an unique instance. I hope I'm right.

···

2009/2/6 Simon Krahnke <overlord@gmx.li>:

Also, using a Class instead of instances is faster since there is no
need of "initialize" for each usage, am I right?

I don't quite understand that question. Classes are instances, too. And
objects without state don't need an initialize method.

--
Iñaki Baz Castillo
<ibc@aliax.net>

No, shared state was meant as we are talking about class attributes.
Also please keep in mind that instances of a class share the code
anyway via instance methods defined in the class.

Kind regards

robert

···

2009/2/6 Julian Leviston <julian@coretech.net.au>:

Think when he said shared state he actually meant shared code. Maybe not.

--
remember.guy do |as, often| as.you_can - without end

What do you mean by faster? For who?

Blog: http://random8.zenunit.com/
Learn rails: http://sensei.zenunit.com/

···

On 06/02/2009, at 9:23 PM, Iñaki Baz Castillo <ibc@aliax.net> wrote:

2009/2/6 Simon Krahnke <overlord@gmx.li>:

Also, using a Class instead of instances is faster since there is no
need of "initialize" for each usage, am I right?

I don't quite understand that question. Classes are instances, too. And
objects without state don't need an initialize method.

Exactly, but in my case, if I'd use objects then I would need
"initiate" method, so in my particular case it is faster to use a
Class. Note that the Class code is initiated during class loading,
since it's an unique instance. I hope I'm right.

--
Iñaki Baz Castillo
<ibc@aliax.net>

LOL yeah,I know

Blog: http://random8.zenunit.com/
Learn rails: http://sensei.zenunit.com/

···

On 06/02/2009, at 7:34 PM, Robert Klemme <shortcutter@googlemail.com> wrote:

2009/2/6 Julian Leviston <julian@coretech.net.au>:

Think when he said shared state he actually meant shared code. Maybe not.

No, shared state was meant as we are talking about class attributes.
Also please keep in mind that instances of a class share the code
anyway via instance methods defined in the class.

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end

What do you mean by faster? For who?

···

2009/2/6 Julian Leviston <julian@coretech.net.au>:
------------------------
class MyClass

  class << self
    puts "Starting MyClass..."
    @my_var = 1
  end

  class << self
    def hello
      puts "hello I'm MyClass"
    end
  end

end

class MyClass2

  def initialize
    puts "Initializing instance of MyClass2..."
    @my_var = 1
  end
  
  def hello
    puts "hello I'm instance of MyClass2"
  end

end

MyClass.hello
MyClass.hello

MyClass2.new.hello
MyClass2.new.hello
------------------------

output:

--------------------
Starting MyClass...
hello I'm MyClass
hello I'm MyClass
Initializing instance of MyClass2...
hello I'm instance of MyClass2
Initializing instance of MyClass2...
hello I'm instance of MyClass2
--------------------

As you see, the MyClass code:
      puts "Starting MyClass..."
    @my_var = 1
is executed *just* at the start of the program, while the code:
    puts "Initializing instance of MyClass2..."
    @my_var = 1
is executed for each MyClass2 initialization (logic of course).

Regards.

--
Iñaki Baz Castillo
<ibc@aliax.net>

LOL yeah I know this, but what did faster mean in that context? More efficient? Less work? Something else?

Blog: http://random8.zenunit.com/
Learn rails: http://sensei.zenunit.com/

···

On 07/02/2009, at 12:27 AM, Iñaki Baz Castillo <ibc@aliax.net> wrote:

2009/2/6 Julian Leviston <julian@coretech.net.au>:

What do you mean by faster? For who?

------------------------
class MyClass

   class << self
       puts "Starting MyClass..."
       @my_var = 1
   end

   class << self
       def hello
           puts "hello I'm MyClass"
       end
   end

end

class MyClass2

   def initialize
       puts "Initializing instance of MyClass2..."
       @my_var = 1
   end

   def hello
       puts "hello I'm instance of MyClass2"
   end

end

MyClass.hello

MyClass2.new.hello
------------------------

output:

--------------------
Starting MyClass...
hello I'm MyClass
Initializing instance of MyClass2...
hello I'm instance of MyClass2
Initializing instance of MyClass2...
hello I'm instance of MyClass2
--------------------

As you see, the MyClass code:
         puts "Starting MyClass..."
       @my_var = 1
is executed *just* at the start of the program, while the code:
       puts "Initializing instance of MyClass2..."
       @my_var = 1
is executed for each MyClass2 initialization (logic of course).

Regards.

--
Iñaki Baz Castillo
<ibc@aliax.net>