bruce (owner)

Revisions

gist: 48086 Download_button fork
public
Public Clone URL: git://gist.github.com/48086.git
Embed All Files: show embed
implementation.rb #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
module LanguageTaxonomy
 
  def self.build(data)
    Node.new(nil, nil, data)
  end
 
  class Node
    include Enumerable
 
    attr_reader :name, :parent, :children
    attr_accessor :value
    def initialize(parent, name, children = [])
      @parent = parent
      @name = name
      @children = children.map do |child|
        Node.new(self, *Array(child))
      end
      add_methods!
    end
 
    def each(&block)
      children.each(&block)
    end
 
    def leaf?
      children.empty?
    end
 
    def to_s(indent = 0)
      indentation = ' ' * indent
      reference = identifier || '(Toplevel)'
      [
        indentation + (identifier || '(Toplevel)'),
        *children.map { |child| child.to_s(indent + 1) }
      ].join("\n")
    end
 
    private
 
    def identifier
      if leaf?
        value ? "#{name}: #{value.inspect}" : name
      else
        name
      end
    end
 
    def add_methods!
      meta = (class << self; self; end)
      children.each do |node|
        meth = node.name.to_s =~ /^\d/ ? "_#{node.name}" : node.name
        if respond_to?(meth)
          raise ArgumentError, "Can not define `#{meth}'"
        end
        meta.instance_eval do
          define_method(meth) { node }
        end
      end
    end
    
  end
 
end
output.txt #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
(Toplevel)
  Roman
    I: "Some value here"
    II
  Majuscule
    A
    B
    Q
      even
      deeper
      down
  Phoenician
    1: "Value for Phoenician 1"
    2
    3
    99
usage.rb #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Rough example
t = LanguageTaxonomy.build([
      ['Roman', ['I', 'II']],
      ['Majuscule',
        [
          'A',
          'B',
          ['Q', ['even', 'deeper', 'down']]
        ]
      ],
      ['Phoenician', ['1', '2', '3', '99']]
    ])
 
t.Roman.I.value = 'Some value here'
t.Phoenician._1.value = 'Value for Phoenician 1'
 
puts t