# Class (not instance) initializers

**URL:** <https://www.ruby-forum.com/t/class-not-instance-initializers/55465>\
**Category:** Ruby\
**Created:** [March 21, 2006, 11:20am UTC](https://www.ruby-forum.com/t/class-not-instance-initializers/55465 "2006-03-21T11:20:28Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Bhrgunatha\_Deva](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/f475e1/32.png) [@Bhrgunatha\_Deva](https://www.ruby-forum.com/u/Bhrgunatha_Deva)\
**Post date:** [March 21, 2006, 11:20am UTC](https://www.ruby-forum.com/t/class-not-instance-initializers/55465/1 "2006-03-21T11:20:28Z")

</div>

Newbie question:

Is there an equivalent to a static constructor in ruby?  
something like:

class MyClass

# want this to run before any instances of MyClass are created

def class\_initialize  
self.some\_complex\_initialisation  
end  
end

At the moment I’m using:  
class MyClass  
def initialize  
@@init = self.some\_complex\_initialisation if @@init.nil?  
end  
end

I’d love to know if there is a more rubyesque way of doing this

Bhrgunatha.

---

<div class="post-metadata">

**Author:** ![Bhrgunatha\_Deva](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/f475e1/32.png) [@Bhrgunatha\_Deva](https://www.ruby-forum.com/u/Bhrgunatha_Deva)\
**Post date:** [March 21, 2006, 12:03pm UTC](https://www.ruby-forum.com/t/class-not-instance-initializers/55465/2 "2006-03-21T12:03:53Z")

</div>

Bhrgunatha Deva wrote:

> end
> 
> At the moment I’m using:  
> class MyClass  
> def initialize  
> @@init = self.some\_complex\_initialisation if @@init.nil?  
> end  
> end
> 
> I’d love to know if there is a more rubyesque way of doing this

Just place your code in the class body:

class MyClass  
@class\_state = complex\_calculation  
end

Often one needs to inform a super class of a new child. This can be  
done with #inherited:

class Base  
def self.inherited(cl)  
print Base, " was inherited by ", cl, “\n”  
end  
end

> > class Foo \< Base  
> > end  
> > Base was inherited by Foo  
> > =\> nil

Kind regards

```
robert
```

---

<div class="post-metadata">

**Author:** ![Bhrgunatha\_Deva](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/f475e1/32.png) [@Bhrgunatha\_Deva](https://www.ruby-forum.com/u/Bhrgunatha_Deva)\
**Post date:** [March 21, 2006, 12:50pm UTC](https://www.ruby-forum.com/t/class-not-instance-initializers/55465/3 "2006-03-21T12:50:00Z")

</div>

Ross B. wrote:

> # =\> nil

I’m so dim. I didn’t realise I could just call a method from inside the  
class body.

Robert K. wrote:

> > > end  
> > > Base was inherited by Foo  
> > > =\> nil

Whoa, that’s very neat!

Thanks.

---

<div class="post-metadata">

**Author:** ![Bhrgunatha\_Deva](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/f475e1/32.png) [@Bhrgunatha\_Deva](https://www.ruby-forum.com/u/Bhrgunatha_Deva)\
**Post date:** [March 21, 2006, 12:51pm UTC](https://www.ruby-forum.com/t/class-not-instance-initializers/55465/4 "2006-03-21T12:51:16Z")

</div>

I am creating a DSL using Ruby. A cut down version is below:

class \_Box  
attr\_accessor :width

```
 def initialize (&block)
            self.width = 20 # some default value
	instance_eval(&block) if block_given?
end

```

end

# Helper function to avoid the DSL user having to use .new

def Box(&block)  
\_Box.new(&block)  
end

I want to do something like:

```
 Box {width = 10}

```

but the only way I can get it to work is

```
 Box {self.width = 10}

```

Having to prefix the ivar with self. makes the DSL look clunky and  
wouldn’t be acceptable to my users.

Is there anyway to avoid the self.? Using {@width = 10} will work  
but prevents some necessary validation from taking place.

I have an alternative where width is a method:

class \_Box  
def width (val = :no\_param)  
if val != :no\_param  
@width = val  
end  
@width  
end  
end

so with this I can write

```
 Box {width 10}

```

which is acceptable from the DSL view point, but makes the getter  
operations more expensive. In the real version a getter operation  
takes about 7 statements to allow for evaluation of block if the ivar  
had been set to a Proc object and inheritance of values from its  
parent object (in a visual hierarchy). The setter operation is often  
only done when the object is created but the getter is done very  
frequently so I want to move down the route of separate setters and  
getters rather than combining them in the one method as an optimization.

Dave.

---

<div class="post-metadata">

**Author:** ![Bhrgunatha\_Deva](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/f475e1/32.png) [@Bhrgunatha\_Deva](https://www.ruby-forum.com/u/Bhrgunatha_Deva)\
**Post date:** [March 21, 2006, 2:34pm UTC](https://www.ruby-forum.com/t/class-not-instance-initializers/55465/5 "2006-03-21T14:34:58Z")

</div>

Dave B. wrote:

> Dave.

Good article on DSLs and addresses your question:  
[http://www.artima.com/rubycs/articles/ruby\_as\_dsl.html](http://www.artima.com/rubycs/articles/ruby_as_dsl.html)

---

<div class="post-metadata">

**Author:** ![Bhrgunatha\_Deva](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/f475e1/32.png) [@Bhrgunatha\_Deva](https://www.ruby-forum.com/u/Bhrgunatha_Deva)\
**Post date:** [March 21, 2006, 12:04pm UTC](https://www.ruby-forum.com/t/class-not-instance-initializers/55465/6 "2006-03-21T12:04:31Z")

</div>

On Tue, 2006-03-21 at 19:20 +0900, Bhrgunatha Deva wrote:

> end  
> Do you mean something like:

class InitMe  
def self.complex\_init  
puts “Initializing #{self}”  
end

complex\_init  
end  
#§ Initializing InitMe

# =\> nil

or even just:

class InitMe  
puts “Initializing #{self}”  
end  
#§ Initializing InitMe

# =\> nil

?

---

<div class="post-metadata">

**Author:** ![Bhrgunatha\_Deva](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/f475e1/32.png) [@Bhrgunatha\_Deva](https://www.ruby-forum.com/u/Bhrgunatha_Deva)\
**Post date:** [March 21, 2006, 4:44pm UTC](https://www.ruby-forum.com/t/class-not-instance-initializers/55465/7 "2006-03-21T16:44:53Z")

</div>

On Tue, 21 Mar 2006, Dave B. wrote:

> # Helper function to avoid the DSL user having to use .new
> 
> Box {self.width = 10}  
> class \_Box  
> Box {width 10}
> 
> which is acceptable from the DSL view point, but makes the getter operations  
> more expensive. In the real version a getter operation takes about 7  
> statements to allow for evaluation of block if the ivar had been set to a  
> Proc object and inheritance of values from its parent object (in a visual  
> hierarchy). The setter operation is often only done when the object is  
> created but the getter is done very frequently so I want to move down the  
> route of separate setters and getters rather than combining them in the one  
> method as an optimization.

here is one simple way:

```
 harp:~ > cat a.rb
 class OpenStruct
   alias_method " __eval__", "instance_eval"
   alias_method " __set__", "instance_variable_set"
   alias_method " __get__", "instance_variable_get"
   instance_methods.each{ |m| undef_method m unless m =~ /^__/ }
   def initialize(&block) __eval__ &block end
   def method_missing m, *a, &b
     m = m.to_s.delete "=?"
     a.size == 0 ? __get__ ("@#{ m }") : __set__ ("@#{ m }", a.shift)
   end
 end

 module Initializable
   def initialize &block
     os = OpenStruct.new &block
     attributes.each{|a| instance_variable_set "@#{ a }", 

```

os. **send** (a)}  
end  
def to\_s  
require “yaml”  
attributes.inject({}){|h,a| h.update a =\> send(a)}.to\_yaml  
end  
def attributes  
self.class::ATTRIBUTES  
end  
end

```
 class Box
   ATTRIBUTES = %w[width height]
   ATTRIBUTES.each{|a| attr a}
   include Initializable
 end

 def Box(*a, &b) Box.new(*a, &b) end

 puts Box {
   width 42
   height 42
 }

 harp:~ > ruby a.rb
 ---
 height: 42
 width: 42

```

the idea is to initialize another object, the OpenStruct in this case,  
and then  
relay the properties. this object can have any ‘slow’ but convenient  
behaviour  
your desire, leaving the Box class to have normal ‘fast’ attributes.

hth.

-a

---

<div class="post-metadata">

**Author:** ![Bhrgunatha\_Deva](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/f475e1/32.png) [@Bhrgunatha\_Deva](https://www.ruby-forum.com/u/Bhrgunatha_Deva)\
**Post date:** [March 21, 2006, 3:18pm UTC](https://www.ruby-forum.com/t/class-not-instance-initializers/55465/8 "2006-03-21T15:18:56Z")

</div>

“Dave B.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote

> Having to prefix the ivar with self. makes the DSL look clunky

I agree, though some experienced Rubyists don’t see it that way.

> move down the route of separate setters and getters rather than combining  
> them in the one method as an optimization.

If you have some guarantees about the ordering of getters and setters,  
you  
can dynamically (re)define the getter and setter at the instance level.  
The  
attached worked for the case of instance variables being initialized  
only  
once, but being read at any time (the context for this was some kind of  
lazy  
creation of an object graph including forward references). Perhaps some  
bits  
of it will apply to your case.

class Object  
def singleton\_class  
class \<\< self; self; end  
end  
end

module LazyForwardRef  
UNDEFINED = nil  
def forward\_ref(attr)  
getter = attr  
setter = (attr.to\_s + ‘=’).intern  
ivar = (‘@’ + attr.to\_s).intern  
suspension = lambda { self.send getter }  
self.singleton\_class.send :define\_method, getter, lambda {  
v = instance\_variable\_get ivar  
if v == UNDEFINED  
suspension  
elsif v.is\_a?(Proc)  
current = v.call  
self.send(setter, current) if current != v  
current  
else v  
end  
}  
self.singleton\_class.send :define\_method, setter, lambda {|val|  
self.instance\_variable\_set ivar, val  
}  
end  
end

require ‘pp’

x = Object.new  
x.extend LazyForwardRef

begin  
p x.foo  
rescue NoMethodError =\> detail  
pp detail  
pp [**LINE** , x, x.methods.sort - Object.instance\_methods]  
end

x.forward\_ref(:foo)  
pp [**LINE** , x, x.methods.sort - Object.instance\_methods]

x.foo  
pp [**LINE** , x, x.foo]

x.foo = ‘Something else’  
pp [**LINE** , x, x.foo]

y = Object.new  
y.extend LazyForwardRef

y.forward\_ref(:bar)  
pp [**LINE** , y, y.methods.sort - Object.instance\_methods]

z = Object.new  
z.extend LazyForwardRef  
z.forward\_ref(:baz)

y.bar = z.baz  
pp [**LINE** , x, y, z, x.foo, y.bar, z.baz, x.foo==z.baz]

x.foo = y.bar  
pp [**LINE** , x, y, x.foo, y.bar]

z.baz= 10  
pp [**LINE** , x, y, z]

pp [**LINE** , x.foo, y.bar, z.baz]

pp [**LINE** , x, y, z]
