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:

"<hello><worldworld>"

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.

Any suggestion for how to store this information
in the module? I want to have the module give
me back the current version of the string it
uses. 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!

···

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

Quoting Marc Heiler (lists@ruby-forum.com):

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

···

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

--
  * Se la Strada e la sua Virtu' non fossero state messe da parte,
* K * Carlo E. Prelz - fluido@fluido.as che bisogno ci sarebbe
  * di parlare tanto di amore e di rettitudine? (Chuang-Tzu)

*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.

···

On Sun, Feb 3, 2013 at 3:43 AM, Carlo E. Prelz <fluido@fluido.as> 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.