Class: Lipa::Node

Inherits:
Object
  • Object
show all
Defined in:
lib/lipa/node.rb

Overview

Base object for all nested object of tree It supports initialization attributes by constant, variable or code

Examples:

tree = Lipa::Tree.new :tree do 
  node :object, :param_1 => 4 do
    param_2 "some_param"
    param_3 run{1+param_3}
  end
end
tree.object.param_1 #=> 4
tree.object.param_2 #=> "some_param"
tree.object.param_3 #=> 5

Direct Known Subclasses

Tree

Constant Summary collapse

@@init_methods =
{:node => self}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, attrs = {}, &block) ⇒ Node



46
47
48
49
50
51
# File 'lib/lipa/node.rb', line 46

def initialize(name, attrs = {}, &block)
  @attrs = attrs
  @attrs[:name] = name.to_s
  @attrs[:children] ||= {}
  instance_eval &block if block_given?
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/lipa/node.rb', line 53

def method_missing(name, *args, &block)
  unless Node.add_node(name, self, *args, &block)
    case args.size
      when 0
        child = @attrs[:children][name]
        return child if child

        val = @attrs[name]
        super unless val
        if val.class == Proc
          instance_eval &(val)
        else
          val
        end
      when 1
        name = name.to_s
        name["="] = "" if name["="]
        @attrs[name.to_sym] = args[0]
      else
        super
    end
  end
end

Instance Attribute Details

#attrsObject

Returns the value of attribute attrs.



43
44
45
# File 'lib/lipa/node.rb', line 43

def attrs
  @attrs
end

Class Method Details

.add_node(name, parent, *args, &block) ⇒ Object

Making children node



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/lipa/node.rb', line 185

def self.add_node(name, parent, *args, &block)
  # OPTIMIZE: This code looks bad
  # Init from kind
  attrs = {}
  args[1] ||= {}
  attrs.merge!(args[1])

  kind = parent.attrs[:tree].kinds[name]
  if kind and kind.for
    init_class = @@init_methods[kind.for]
    attrs[:kind] = kind.name
    attrs.merge!(kind.attrs) do |key,v1,v2|
      v1
    end
  else
    #from init methods
    init_class = @@init_methods[name]
  end

  if init_class
    attrs[:parent] = parent
    attrs[:tree] = parent.attrs[:tree]
    child_name = args[0].to_sym

    existen_child = parent.attrs[:children][child_name]
    attrs = existen_child.attrs.merge(args[1]) if existen_child

    args[1].merge!(attrs) do |key,v1,v2| 
      v1
    end

    if kind
      parent.attrs[:children][child_name] = init_class.send(:new, *args.clone, &kind.block)
      parent.attrs[:children][child_name].attrs.merge!(attrs)
      parent.attrs[:children][child_name].instance_exec(&block) if block_given?
    else
      parent.attrs[:children][child_name] = init_class.send(:new, *args, &block )
    end
    true
  else  
    nil
  end
end

.init_methods(*names) ⇒ Object

Accesor for methods for initialization node objects

Examples:

class Folder < Lipa::Node
  init_methods :folder
end

fls = Lipa::Tree.new :folders do
  folder :folder_1 do
    param_1 "some_param
  end
end

fls.folder_1.class #=> Folder


169
170
171
172
173
174
175
176
177
# File 'lib/lipa/node.rb', line 169

def self.init_methods(*names)
  if names.size > 0
    names.each do |name|
      @@init_methods[name.to_sym] = self
    end
  else
    @@init_methods
  end
end

Instance Method Details

#[](path) ⇒ Node

Accessor for node by path in Unix style

Examples:

dir_2["dir_1/dir_2/searched_obj"] 
dir_2["searched_obj"] 
dir_2["./searched_obj"] 
dir_2["../dir_2/searched_obj"] 


86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/lipa/node.rb', line 86

def [](path)
  split_path = path.split("/")   
  obj = case split_path[0]
  when ""
    @attrs[:tree]
  when ".."
    @attrs[:parent]
  when "."
    self
  else
    @attrs[:children][split_path[0].to_sym]
  end

  if obj
    if split_path.size > 1
      obj[split_path[1..-1].join("/")]
    else
      obj
    end
  end
end

#ref(path) ⇒ Object

Reference to othe object

Examples:


node :node_1 
node :node_2 do
  param_1 ref("../node_1")
end


148
149
150
# File 'lib/lipa/node.rb', line 148

def ref(path) 
 Proc.new { self[path] }
end

#run(&block) ⇒ Object

Wraping code in attribute

Examples:

Tree.new :tree do
  param_1 10
  param_2 run{ param_1 * 10 }
end


135
136
137
# File 'lib/lipa/node.rb', line 135

def run(&block)
  block
end

#with(attrs = {}, &block) ⇒ Object

Initial method for group description

Examples:

tree = Lipa::Tree.new :tree do 
  with :param_1 => "some_param" do
    node :obj_1
    node :obj_2
  end
end

tree.obj_1.param_1 #=> "some_param"
tree.obj_2.param_1 #=> "some_param"


120
121
122
123
124
# File 'lib/lipa/node.rb', line 120

def with(attrs = {}, &block)
  if block_given?
    Lipa::Bunch.new(self, attrs, &block)
  end
end