# Initialize a variable in an extended class

**URL:** <https://www.ruby-forum.com/t/initialize-a-variable-in-an-extended-class/98355>\
**Category:** Ruby\
**Created:** [July 14, 2006, 1:55am UTC](https://www.ruby-forum.com/t/initialize-a-variable-in-an-extended-class/98355 "2006-07-14T01:55:31Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![xmg-eric](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/x/f04885/32.png) [@xmg-eric](https://www.ruby-forum.com/u/xmg-eric)\
**Post date:** [July 14, 2006, 1:55am UTC](https://www.ruby-forum.com/t/initialize-a-variable-in-an-extended-class/98355/1 "2006-07-14T01:55:31Z")

</div>

Interesting problem. There is undoubtedly much to  
will learn from suggested solutions. Here it is:

I’m working with xhtml data, and want to extend  
the REXML Element type with an inline? method that  
returns true when  
%w(a b code em emphasis i strong tt).member?(name)

That would be a simple addition to the Element class,  
except that the program already contains an @inline  
variable, and I don’t want to repeat myself. (Important,  
because   
 is not considered an inline tag at the  
moment. If at some point it turns out to be a good idea,  
I want one list to modify, rather than two.)

The question is: How do I make the contents of the  
variable known to the Element class?

## Possibilities:

a) Use a global variable. This should work:  
class REXML::Element  
def inline?  
return $inline.member?(name)  
end  
end

```
 Of course, we don't much like global variables.
 But that's one way to single-source the data and
 make it available in two different classes.

```

b) Use a class variable:  
class REXML::Element  
@@inline = %w(a b code em emphasis i strong tt)  
def inline?  
return @@inline.member?(name)  
end  
end

```
 Note: For a long time it wasn't clear to me that
 it is impossible to initialize an instance variable
 outside of a method. Coming from the Java world, I
 just assumed that this would be legal:
   class Foo
     @bar = 2
   end

 But it isn't. (A fact that needs to be spelled out
 somewhere, for Java types.) Class variables can be
 initialized outside of a method, though, so this
 solution works--but it violates the DRY principle.

 Is there a way to use the data stored in the @inline
 variable? Perhaps by using eval or instance_eval?

```

c) Add an an additional initialize call? Does this  
work?  
class REXML::Element  
def initialize  
@inline = %w(a b code em emphasis i strong tt)  
end

```
     def inline?
      return @inline.member?(name)
     end
   end

 This also leaves the DRY problem untouched, but
 I find myself wondering whether initialize()
 invocations are additive, as well. (I thought I
 saw that once, but have been unable to find any
 reference to the concept.)

```

d) Do some other clever thing with closures or eval,  
so the Element object can reference data defined  
in my class? Is there a way to do that?

Looking forward to responses. Much learning awaits.  
:\_)

---

<div class="post-metadata">

**Author:** ![xmg-eric](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/x/f04885/32.png) [@xmg-eric](https://www.ruby-forum.com/u/xmg-eric)\
**Post date:** [July 14, 2006, 2:05am UTC](https://www.ruby-forum.com/t/initialize-a-variable-in-an-extended-class/98355/2 "2006-07-14T02:05:35Z")

</div>

On 7/14/06, Eric A. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> variable, and I don’t want to repeat myself. (Important,  
> class REXML::Element  
> class REXML::Element  
> class Foo
> 
> ```
> end
> 
> ```
> 
> Looking forward to responses. Much learning awaits.  
> :\_)

Use a constant:

```
  class REXML::Element
    INLINE = %w(a b code em emphasis i strong tt)
    def inline?
     INLINE.member?(name)
    end
  end

```

BTW

> Coming from the Java world, I  
> just assumed that this would be legal:  
> class Foo  
> @bar = 2  
> end
> 
> ```
> But it isn't.
> 
> ```

It is, it just doesn’t do what you were expecting. Instead of  
initialising an instance variable belong to an instance of the class,  
it initialises an instance variable belonging to the instance of Class  
that is the class definition. A class is an object too.

Regards,  
Sean

---

<div class="post-metadata">

**Author:** ![xmg-eric](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/x/f04885/32.png) [@xmg-eric](https://www.ruby-forum.com/u/xmg-eric)\
**Post date:** [July 14, 2006, 2:39am UTC](https://www.ruby-forum.com/t/initialize-a-variable-in-an-extended-class/98355/3 "2006-07-14T02:39:10Z")

</div>

Hi –

On Fri, 14 Jul 2006, Eric A. wrote:

> Note: For a long time it wasn’t clear to me that  
> it is impossible to initialize an instance variable  
> outside of a method. Coming from the Java world, I  
> just assumed that this would be legal:  
> class Foo  
> @bar = 2  
> end
> 
> But it isn’t. (A fact that needs to be spelled out  
> somewhere, for Java types.)

I’m not sure what you mean by “somewhere”. It gets talked about and  
explained regularly here, as well as in various books, wikis, etc.  
The workings of instance variables are not a closely guarded secret  
🙂

When you see this:

@var

you are seeing an instance variable belonging to whatever object is,  
at that point, playing the role of “self” (the default object).

At the top level of a class definition block, “self” is the class  
object (Foo in your example).

So in your example, you’ve got an instance variable belonging to the  
class object Foo. There’s no connection at all between this instance  
variable and any instance variable that may come into being later when  
some other object is “self” (including an instance of Foo).

David

---

<div class="post-metadata">

**Author:** ![xmg-eric](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/x/f04885/32.png) [@xmg-eric](https://www.ruby-forum.com/u/xmg-eric)\
**Post date:** [July 14, 2006, 2:42am UTC](https://www.ruby-forum.com/t/initialize-a-variable-in-an-extended-class/98355/4 "2006-07-14T02:42:28Z")

</div>

removed\_email\_address@domain.invalid wrote:

> > But it isn’t. (A fact that needs to be spelled out  
> > somewhere, for Java types.)
> 
> I’m not sure what you mean by “somewhere”. It gets talked about and  
> explained regularly here, as well as in various books, wikis, etc.  
> The workings of instance variables are not a closely guarded secret  
> 🙂

Thanks for the smiley. I haven’t been spending enough time  
here, it seems.  
:\_)

> So in your example, you’ve got an instance variable belonging to the  
> class object Foo. There’s no connection at all between this instance  
> variable and any instance variable that may come into being later when  
> some other object is “self” (including an instance of Foo).

Getting clearer all the time.  
thanks.

Now for the bigger problem… how to reuse data when  
I’m extending an existing class…

---

<div class="post-metadata">

**Author:** ![xmg-eric](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/x/f04885/32.png) [@xmg-eric](https://www.ruby-forum.com/u/xmg-eric)\
**Post date:** [July 14, 2006, 2:39am UTC](https://www.ruby-forum.com/t/initialize-a-variable-in-an-extended-class/98355/5 "2006-07-14T02:39:19Z")

</div>

Sean O’Halpin wrote:

> > 
> 
> Use a constant:
> 
> ```
> class REXML::Element
> INLINE = %w(a b code em emphasis i strong tt)
> def inline?
> INLINE.member?(name)
> end
> end
> 
> ```

Yup. Another good alernative. Do I then I share that  
constant with the surrounding program like this:

```
INLINE = REXML::Element::INLINE

```

It would be better to access the constant defined  
in my class:

class Main  
INLINE = %w(a b code em emphasis i strong tt)  
attr\_reader :INLINE

```
 class REXML::Element
   def inline?
     return Main.INLINE.member?(name)
   end
 end

```

end

But that doesn’t seem to work…  
error: in `inline?': undefined method`INLINE’ for  
MY\_MODULE::Main:Class (NoMethodError)

> It is, it just doesn’t do what you were expecting. Instead of  
> initialising an instance variable belong to an instance of the class,  
> it initialises an instance variable belonging to the instance of Class  
> that is the class definition. A class is an object too.

Ah ha! I knew it was there when the class is being read, but  
not when the object is constructed. I didn’t quite realize  
that it is still there as part of the class definition. That  
helps to refine my mental model. Thanks much.

---

<div class="post-metadata">

**Author:** ![xmg-eric](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/x/f04885/32.png) [@xmg-eric](https://www.ruby-forum.com/u/xmg-eric)\
**Post date:** [July 14, 2006, 3:22am UTC](https://www.ruby-forum.com/t/initialize-a-variable-in-an-extended-class/98355/6 "2006-07-14T03:22:39Z")

</div>

On Fri, 14 Jul 2006, Eric A. wrote:

> d) Do some other clever thing with closures or eval,  
> so the Element object can reference data defined  
> in my class? Is there a way to do that?

why not a module?

module ElementExtension  
TAGS = %w( i p foo bar )

```
 def inline?
   TAGS.include? name
 end

```

end

REXML::Element.extend ElementExtension

-a

---

<div class="post-metadata">

**Author:** ![xmg-eric](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/x/f04885/32.png) [@xmg-eric](https://www.ruby-forum.com/u/xmg-eric)\
**Post date:** [July 14, 2006, 3:44am UTC](https://www.ruby-forum.com/t/initialize-a-variable-in-an-extended-class/98355/7 "2006-07-14T03:44:48Z")

</div>

Yes! That is indeed clever. I overlooked  
the extend method.

I’m probababy going to be kicking myself for  
not figuring out the rest of the solution,  
but I’ll ask anyway:

```
What's the best way to share TAGS between
this module and my main module?

```

Also:  
Where is the best place to read about  
modules. I have yet to grok their essence,  
as shown by this example and my HTree  
question!
