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. 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!
on 2013-02-03 10:12
on 2013-02-03 10:44
Subject: Storing string-data in a module Date: dom 03 feb 13 06:12:20 +0900 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
on 2013-02-04 09:25
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. *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.
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.