Jano Svitok
11/13/2006 3:03:00 PM
On 11/13/06, jan aerts (RI) <jan.aerts@bbsrc.ac.uk> wrote:
> Hi all,
>
> I'm trying to create a little library for drawing my data using SVG. One
> of the inherent properties of the drawings that I have to make, is that
> each picture can contain one or more tracks with each track containing
> one or more features (see ASCII art below).
>
> +----------------------------picture-+
> | +----------------------track1----+ |
> | | | |
> | | x x | |
> | | x x | |
> | | | |
> | | | |
> | +--------------------------------+ |
> | |
> | +----------------------track2----+ |
> | | | |
> | | xx | |
> | +--------------------------------+ |
> +------------------------------------+
>
> As a track can _only_ be defined within a picture, and a feature can
> _only_ be defined within a track, I have set up the classes as follows:
> class Picture
> class Track
> class Feature
> end
> end
> end
>
> The problem is that some of the properties of a Picture object have to
> be readable for its Track objects. This is _not_ simple inheritance,
> because Picture and Picture::Track are two completely different things.
> As I see it, there are several options:
> (A) either pass those properties as arguments every time you create a
> new Picture::Track object. Not optimal, because the same piece of data
> is copied over and over again.
> (B) set those features as global variables. Not optimal as well.
> (C) something more elegant?
>
> More elaborately (showing some of the key features)
> <LIB CODE SNIPPET>
> class Picture
> def initialize(width)
> @width = width
> @tracks = Array.new
> end
> attr_accessor :width, :tracks
>
> def add_track(name)
> @tracks.push(Picture::Track.new(name)
> return @tracks[-1]
> end
>
> class Track
> # DO NOT CALL INITIALIZE METHOD DIRECTLY: use Picture#add_track
> def initialize(name)
> @name = name
> end
> attr_accessor :name
>
> def to_svg
> # I NEED THE WIDTH OF THE PICTURE HERE
> return
> some_xml_that_includes_the_width_which_was_defined_in_Picture
> end
>
> class Feature
> ...
> end
> end
> end
> </LIB CODE SNIPPET>
>
> <USAGE SNIPPET>
> p = Picture.new(800) # Creates a new picture of 800pt width.
> p.add_track('first_track')
> p.add_track('second_track')
> </USAGE SNIPPET>
>
> In the end, the question is: should I make Picture#width a global
> variable, should I add width as an argument to
> Picture::Track#initialize, or is there a more elegant solution? (I hope
> it's the last one...)
>
> Any help would be very much appreciated,
> jan.
Hi,
two ideas:
1. pass the picture (it)self to the Track constructor and then query
whatever you need
2. have all the svg generating stuff in another class that will be
given the Picture object, and will iterate through it, creating the
xml along the way (ERB template comes to my mind...)
Jan