Search code examples
rubyobjectdirectory-structure

Directory-type structure in plain ruby


I'm working on a novel generator in Ruby (my first project) and I'm building the fictional world system for that generator. I'm trying to build a directory-like structure with my settings. So, for example, I create an "Earth" setting and it contains "North America" and that contains "USA."

The way I'm doing it right now, I initialize each Setting with an optional supersetting (otherwise it's nil) and then I have an add_setting method that creates a new Setting with self as the super and adds it to an array where it's all tracked. Then it's pretty easy for me to add other methods to go up or down the chain to find parents and children.

def initialize(name, supersetting = nil,subsettings = [])
    @name = name
    @supersetting = supersetting
    @subsettings = subsettings
end

def add_setting(name)
    new_setting = Setting.new(name, self)
    @subsettings.push(new_setting)
end

def tree
    tree = []
    setting = self
    while !(setting == nil) do
        tree.unshift(setting.name)
        setting = setting.supersetting
    end
    tree
end

def all_subsettings
    all = @subsettings
    @subsettings.each do |sub|
        all = all + sub.all_subsettings
    end
    all 
end


earth = Setting.new("Earth")
earth.add_setting("North America")
earth.subsettings[0].add_setting("USA")
earth.subsettings[0].subsettings[0].add_setting("Virginia")
earth.subsettings[0].subsettings[0].add_setting("Washington, D.C.")
earth.subsettings[0].subsettings[0].subsettings[0].add_setting("Alexandria")
earth.subsettings[0].subsettings[0].subsettings[0].add_setting("Richmond")
earth.subsettings[0].subsettings[0].subsettings[1].add_setting("Georgetown")   
p earth.see_all_subsettings  
p earth.name_all_subsettings

yields

["Earth > North America", "Earth > North America > USA", "Earth > North America > USA > Virginia", "Earth > North America > USA > Washington, D.C.", "Earth > North America > USA > Virginia > Alexandria", "Earth > North America > USA > Virginia > Richmond", "Earth > North America > USA > Washington, D.C. > Georgetown"]

["North America, Earth", "USA, North America, Earth", "Virginia, USA, North America, Earth", "Washington, D.C., USA, North America, Earth", "Alexandria, Virginia, USA, North America, Earth", "Richmond, Virginia, USA, North America, Earth", "Georgetown, Washington, D.C., USA, North America, Earth"]

As you can see it gets cumbersome if I want to modify or add individual elements, because I have all these nested calls. And I kind of have to know where things are, which won't be practical when I really start building things here.

What I want is this to behave more like a directory, where I have a pointer that tells me where I am, and then I can quickly call the object at however many layers deep I am, because the first part of the path is already known. I'm trying to figure out how to do this - thinking vaguely in hashes and lookup functions right now - but before I get too far into it, what's the term for what I'm trying to do? Is it harebrained to be doing this in plain ruby instead of learning a framework? Any conceptual stuff or strategems for solving problems like this?

Sorry for all the generalities, folks. I'm new to coding and don't really know enough to ask the questions more concisely.


Solution

  • add_setting("North America") return array of Settings as well, so you can do something like this:

    earth = Setting.new("Earth"); 
    earth.add_setting("North America").add_setting("USA").add_setting("Virginia")
    

    in other words you should be able to do this:

    earth = Setting.new("Earth"); 
    north_america = earth.add_setting("North America"); 
    virginia = north_america.add_setting("virginia");