I’m building a parser class which uses a separate token class to store
regexes about to help recognize custom markup tags.
class Tokens
attr_reader( :start_link, :end_link, :bold )
def initialize
@start_link = /[[/
@end_link = /]]/
@bold = /**/
end
end
The attr_reader line looks clumsy to me. Is there a way to get the class to
automatically allow for any instance variable to be given the attr_reader
characteristic? This list could get quite long and while I am using
Test::Unit to keep from breaking things the more I fix them. Mostly I’m
lazy and I’d prefer not to have to add a variable name in two places.
Thanks for your help.
michael libby x@ichimunki.com writes:
The attr_reader line looks clumsy to me. Is there a way to get the class to
automatically allow for any instance variable to be given the attr_reader
characteristic?
THe class doesn’t know it’s instance variables: they only appear in
the actually instances when first used (that is, each instance could
potentially have a different set of instance variables). The code
below is kind of dangerous, but dynamically defines reader methods for
any otherwise unknown method call:
class Dave
def method_missing(name, *args)
fail "No one expects the extra args" unless args.empty?
type.class_eval "attr_reader :#{name}"
send name
end
def initialize
@a = 1
@b = "cat"
@c = /abc/
end
end
d = Dave.new
p d.a
p d.b
p d.c
If there was some point at which you knew all your instance variables
were set, you could always use the Object#instance_variables method to
iterate over them and create accessors.
Cheers
Dave
I’m building a parser class which uses a separate token class to store
regexes about to help recognize custom markup tags.
If these tokens are a static entity (ie. they are predefined), then you
can use a Struct.
In which case your Tokens class becomes:
Tokens = Struct.new(“Tokens”, :start_link, :end_link, :bold)
t = Tokens.new(/[[/, /]]/, /**/)
Which does the same thing as your Token class below, with the addition
that the Struct also provides “attr_writer” for each attribute of the
Tokens class.
class Tokens
attr_reader( :start_link, :end_link, :bold )
def initialize
@start_link = /[[/
@end_link = /]]/
@bold = /**/
end
end
The following is from ‘ri Struct’. “A Struct is a convenient way to
bundle a number of attributes together, using accessor methods, without
having to write an explicit class.” That seems to me to be what you
want.
-Michael