Storing string-data in a module

Hi.

I have big module with many tiny methods. These methods
all return a string.

Example:

module Foo

def one(i = '')
  return '<'+i+'>'
end

def two(i = '')
  return '<'+i+i+'>'
end

end

So far so good. Please note that this is just a short
demo, a simplification. The real module is huge, and
much more complicated. But I just want to demo something
relevant for my question.

Now, I include this module into class bar.

class Bar

include Foo

attr_reader :string

def initialize
@string = ‘’
build_string
end
def build_string
@string << one(‘hello’)
@string << two(‘world’)
end
end

x = Bar.new
x.string

Ok this will return this string:

“”

So far, everything works correctly.

As you can see, in class Bar I can use an @ivar,
in this case @string.

Now, however, I also want to be able to store
this in the module. But how can I do this?

I could use a global variable, but this is awful.

I could use a constant, like X = [’’] and
append to that in the module, but this is
also awful.

Why would I want this? Because a module is more
flexible than a class - I can use the module
to mix it into other classes AND I could use
the module standalone. When I would use a class
alone, I could no longer mix it into other
classes. I could only subclass, but subclass
mandates and enforces a strict hierarchy, which
I really do not want or need in ALL my uses
cases, so I am stuck keeping this as a module.

Help!!!

Any suggestion for how to store this information
in the module additionally? I want to have the module
give me back the current version of the string it
uses (internally). And I also must keep the core
functionality of including all those methods in
the module into my new, more specialized classes.

Any HELPFUL suggestions welcome!

Subject: Storing string-data in a module
Date: dom 03 feb 13 06:12:20 +0900

Quoting Marc H. ([email protected]):

Now, however, I also want to be able to store
this in the module. But how can I do this?

I might be mistaken, but I believe you cannot. There are global
variables (prepended by ‘$’), class variables (prepended by ‘@@’) and
instance variables (prepended by ‘@’). But there are, to my knowledge,
no module variables. And this is exactly why modules are more
flexible: they provide methods, but they do not provide instantiation
or storage. From what I know, a module can only own constants
(immutable).

I believe this boils down to the usual multiple-inheritance-related
class of FAQ’s. IMO, Ruby’s designers have decided to avoid multiple
inheritance not because it is evil, but because the sheer amount of
unescapable, tangled complexity brought in at language implementation
level
by multiple inheritance would produce a clumsier language as a
whole. I back their decision single-heartedly.

If I were facing your problem, I would pass the string as the first
parameter to all functions in the module, like this:

def one(string,i='')
  string+='<'+i+'>'
end

You can directly use the instance’s variable, like this:

def one(i = '')
  @string+='<'+i+'>'
end

@string would be owned by the instance of each class that included
your module. But I think this last way obfuscates things a bit too
much.

Carlo

On Sun, Feb 3, 2013 at 3:43 AM, Carlo E. Prelz [email protected] wrote:

You can directly use the instance’s variable, like this:

def one(i = '')
  @string+='<'+i+'>'
end

@string would be owned by the instance of each class that included
your module. But I think this last way obfuscates things a bit too
much.

Much agreed – this would result in, effectively, a side-effect, or
action at a distance, and create a coupling with the including class
that may come back to bite one.