> Lähettäjä: "Trans" <transfire@gmail.com>
> Aihe: Complex Library Object/Class and its Interface
>
> Been beating my head against this one for far too long now, and I think
> others might be interested in it. I have a lib where the user needs to
> define a set of "things" that have both assignable data and assignable
> functions. Also they should be extensible so the user can add
> additional functionality. It's a bit difficult to explain so I will
> just give my exmaple.
>
> |class Parser::Token
> |
> | class << self
> | def esc(str) ; Regexp.escape(str) ; end
> | def unit? ; @unit ; end
> | def unit(u) ; @unit = ( u ? true : false ) ; end
> | def exclusive? ; @exclusive ; end
> | def exclusive(excl) ; @exclusive = ( excl ? true : false ) ; end
> | def priority ; @priority ||= 10 ; end
> | def priority(pri) ; @priority = pri ; end
> | def <=> ; @priority ; end
> | def start_exp(match=nil) ; @start.call(match) ; end
> | def start(&blk) ; @start = blk ; end
> | def stop_exp(match=nil) ; @stop.call(match) ; end
> | def stop(&blk) ; @stop = blk ; end
> | end
> |
> | attr_reader :parent, :match, :body
> |
> | def initialize( parent, match )
> | @parent = parent
> | @match = match
> | @body = []
> | end
> |
> | def <<( content ) ; @body << content ; end
> | def last ; @body.empty? ? @body : @body.last ; end
> | def empty? ; @body.empty? ; end
> | def pop ; @body.pop ; end
> | def each(&blk) ; @body.each(&blk) ; end
> |
> |end #class Parser::Token
>
> So then the lib usr can define each of their "things" based on this,
> minimally:
>
> |class Marker < Parser::Token
> |
> | exclusive false
> | start { %r{ \< (.*?) \> }mx }
> | stop { |match| %r{ \< [ ]* (#{esc(match[1])}) (.*?) \. \> }mx }
> |
> | #... user's optional methods ...
>
> It toke me some time to work this out in itself. And I thought I had
> finally gotten a fairly nice interface here. But to my dismay, I just
> discovered that I can't subclass Marker b/c I loose the definitions of
> the above attributes (ie. exclusive, start, stop). So now I'm back to
> rethinking the whole setup. (Also note that if the user's methods
> redefine #initialize or the other Token methods, it might cause the
> parser that uses it to break --another slight down side and a possible
> use case for RCR #198)
>
> So how does one properly build something like this in a nice neat way?
> Thanks,
> T.
I think you may be making this more difficult than it is. What
are you trying to achieve? Just reduce the syntax or are you
intending for Parser to automatically be able to use the user-
defined class? Conventionally:
class Token
def init
@var = 'foo'
end
def fun
# ...
end
attr_accessor :some_attr
end
class Marker < Token
def initialize
super
end
# fun is available here
# some_attr is available here
# @var is available here
def my_fun
# ...
end
end
E