# Got to be a better way to code class variables

**URL:** <https://www.ruby-forum.com/t/got-to-be-a-better-way-to-code-class-variables/190521>\
**Category:** Ruby\
**Created:** [June 22, 2010, 2:04am UTC](https://www.ruby-forum.com/t/got-to-be-a-better-way-to-code-class-variables/190521 "2010-06-22T02:04:54Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![daveh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/85e7bf/32.png) [@daveh](https://www.ruby-forum.com/u/daveh)\
**Post date:** [June 22, 2010, 2:04am UTC](https://www.ruby-forum.com/t/got-to-be-a-better-way-to-code-class-variables/190521/1 "2010-06-22T02:04:54Z")

</div>

I’m trying to set up an object with overridable defaults, so it will act  
like this:

> > s1 = Smee.new  
> > =\> #\<Smee:0x102007618 @middle=nil, @front=nil, @back=nil\>
> 
> > s1.middle = ‘hi’  
> > =\> “hi”
> 
> > s1  
> > =\> #\<Smee:0x102007618 @middle=“hi”, @front=nil, @back=nil\>
> 
> > Smee.front = “O”  
> > =\> “O”
> 
> > s2 = Smee.new  
> > =\> #\<Smee:0x101ffdbb8 @middle=nil, @front=“O”, @back=nil\>
> 
> > s1 =\> #\<Smee:0x102007618 @middle=“hi”, @front=“O”, @back=nil\>  
> > Smee.middle = “utu”  
> > =\> “utu”
> 
> > s1.middle  
> > =\> “hi”
> 
> > s2.middle  
> > =\> “utu”

So I can set the properties of an instance of Smee, but if I don’t set  
them, or if I set them back to nil, then the corresponding values that I  
set on the class will take their place.

This is the closest thing I’ve gotten so far and it seems ludicrously  
clunky.

class Smee  
attr\_writer :front, :middle, :back

```
class << self
  attr_accessor :front, :middle, :back
end

def front
  @front || Smee.front
end

def middle
  @middle || Smee.middle
end

def back
  @back || Smee.back
end

```

end

I’d like to have other methods that worked the same on the class and the  
instance, but the only way I can figure out how is to type every single  
method twice. There has _got_ to be some terribly clever ruby-esque way  
of including instance methods as class methods or vice versa, no?

---

<div class="post-metadata">

**Author:** ![daveh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/85e7bf/32.png) [@daveh](https://www.ruby-forum.com/u/daveh)\
**Post date:** [June 22, 2010, 2:42am UTC](https://www.ruby-forum.com/t/got-to-be-a-better-way-to-code-class-variables/190521/2 "2010-06-22T02:42:57Z")

</div>

Dave H. wrote:

> > > s2 = Smee.new
> 
> ```
> @front || Smee.front
> 
> ```
> 
> I’d like to have other methods that worked the same on the class and the instance, but the only way I can figure out how is to type every single method twice. There has _got_ to be some terribly clever ruby-esque way of including instance methods as class methods or vice versa, no?

Some metaprogging…

module Overridable  
def overridable(\*names)  
names.each do |name|  
attr\_writer name  
(class \<\< self; self; end).class\_eval do  
attr\_accessor name  
end  
class\_eval %{  
def #{name}  
@#{name} || self.class.#{name}  
end  
}  
end  
end  
end

class Smee  
extend Overridable

overridable :front  
self.front = 12  
end

sm0 = Smee.new

sm1 = Smee.new  
sm1.front = 56

p sm0.front, sm1.front

---

<div class="post-metadata">

**Author:** ![daveh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/85e7bf/32.png) [@daveh](https://www.ruby-forum.com/u/daveh)\
**Post date:** [June 22, 2010, 10:06am UTC](https://www.ruby-forum.com/t/got-to-be-a-better-way-to-code-class-variables/190521/3 "2010-06-22T10:06:39Z")

</div>

2010/6/22 Joel VanderWerf [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

> Dave H. wrote:
> 
> > I’m trying to set up an object with overridable defaults, so it will act like this:

Question is, do you really need this:

> > I’d like to have other methods that worked the same on the class and the instance, but the only way I can figure out how is to type every single method twice. There has _got_ to be some terribly clever ruby-esque way of including instance methods as class methods or vice versa, no?

? You only need setters on the class if you want to be able to modify  
the default. If not, you can use a different approach (see below).

> Some metaprogging…

Some more metaprogramming:

> <https://gist.github.com/rklemme/448155>

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![daveh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/85e7bf/32.png) [@daveh](https://www.ruby-forum.com/u/daveh)\
**Post date:** [June 22, 2010, 9:49pm UTC](https://www.ruby-forum.com/t/got-to-be-a-better-way-to-code-class-variables/190521/4 "2010-06-22T21:49:48Z")

</div>

Dave H. wrote:

> class Smee  
> extend SmeeCore # including it for the _class_  
> include SmeeCore # including it for the _instances_  
> end

If you want the extend to happen automatically when you include a  
module, you can define an included method on M that does it:

module M  
def foo  
“FOO”  
end  
def self.included©  
c.extend M  
end  
end

class C  
include M  
end

p C.foo  
p C.new.foo

---

<div class="post-metadata">

**Author:** ![daveh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/85e7bf/32.png) [@daveh](https://www.ruby-forum.com/u/daveh)\
**Post date:** [June 22, 2010, 8:32pm UTC](https://www.ruby-forum.com/t/got-to-be-a-better-way-to-code-class-variables/190521/5 "2010-06-22T20:32:30Z")

</div>

On Jun 22, 2010, at 1:06 , Robert K. wrote:

> 2010/6/22 Joel VanderWerf [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)
> 
> > Dave H. wrote:
> > 
> > > I’m trying to set up an object with overridable defaults, so it will act like this:
> 
> Question is, do you really need this:

Good question. I’m not sure yet.

> > > I’d like to have other methods that worked the same on the class and the instance, but the only way I can figure out how is to type every single method twice. There has _got_ to be some terribly clever ruby-esque way of including instance methods as class methods or vice versa, no?
> 
> ? You only need setters on the class if you want to be able to modify  
> the default. If not, you can use a different approach (see below).

What I’m trying to do is save myself a bunch of time and effort coding a  
web site. The class will contain the ‘default’ web page, and then  
various routines will be able to tweak the title, or the main contents,  
to fit the specific page the user is on. But, I’d also like to be able  
to change the ‘default’ page properties as well, as conditions warrant.  
I could just store everything in some kind of cloud-y, tree-y, nest-y  
sort of structure, but the class/instance structure seemed like a good  
place to start.\*

Then when I tried it, and ended up with rather goofy looking code, it  
became an opportunity to learn more about Ruby. Playing with Joel’s code  
taught me something absolutely nifty-keen: the difference between  
“include” and “extend”.

I made a brief mention in my original post that I also wanted to have  
some methods that would also appear on both the class and the instance.  
I ended up with this solution:

module SmeeCore  
def pushmepullyu  
@back = @front  
end  
def double  
@front = @front \* 2  
end  
end

class Smee  
extend SmeeCore # including it for the _class_  
include SmeeCore # including it for the _instances_  
end

- I suspect I’m going to discover that the class properties are more  
global than I’d originally thought, and my instance properties are going  
to have to become a lot more sophisticated and start handling ‘regional’  
defaults: less than global, more than local.
