Class: HackTree::Instance

Inherits:
Object
  • Object
show all
Defined in:
lib/hack_tree/instance.rb

Overview

Instance of the system.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attrs = {}) ⇒ Instance

Returns a new instance of Instance.



10
11
12
13
# File 'lib/hack_tree/instance.rb', line 10

def initialize(attrs = {})
  clear
  attrs.each {|k, v| send("#{k}=", v)}
end

Instance Attribute Details

#confObject

Configuration object.



5
6
7
# File 'lib/hack_tree/instance.rb', line 5

def conf
  @conf
end

#nodesObject

Array of Node::Base successors.



8
9
10
# File 'lib/hack_tree/instance.rb', line 8

def nodes
  @nodes
end

Instance Method Details

#actionObject

Create action object.

>> r.action
hello       # Say hello

>> r.action.hello
Hello, world!


22
23
24
# File 'lib/hack_tree/instance.rb', line 22

def action
  ActionContext.new(self)
end

#children_of(parent) ⇒ Object

List direct children of node. Return Array, possibly an empty one.

children_of(nil)    # => [...], children of root.
children_of(node)   # => [...], children of `node`.


30
31
32
# File 'lib/hack_tree/instance.rb', line 30

def children_of(parent)
  @nodes.select {|node| node.parent == parent}
end

#clearObject



34
35
36
37
# File 'lib/hack_tree/instance.rb', line 34

def clear
  clear_conf
  clear_nodes
end

#clear_confObject



39
40
41
42
43
44
45
46
47
48
# File 'lib/hack_tree/instance.rb', line 39

def clear_conf
  @conf = Config.new({
    :brief_desc_stub => "(no description)",
    :global_name_align => 16..32,
    :group_format => "%s/",
    :hack_format => "%s",
    :local_name_align => 16..32,
  })
  nil
end

#clear_nodesObject



50
51
52
53
# File 'lib/hack_tree/instance.rb', line 50

def clear_nodes
  @nodes = []
  nil
end

#completion_logic(input, options = {}) ⇒ Object

Perform logic needed to do IRB completion. Returns Array if completion is handled successfully, nil if input is not related to HackTree.

completion_logic("c.he", :enabled_as => :c)    # => ["c.hello"]

Raises:

  • (ArgumentError)


59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/hack_tree/instance.rb', line 59

def completion_logic(input, options = {})
  o = {}
  options = options.dup

  o[k = :enabled_as] = options.delete(k)

  raise ArgumentError, "Unknown option(s): #{options.inspect}" if not options.empty?
  raise ArgumentError, "options[:enabled_as] must be given" if not o[:enabled_as]

  # Check if this input is related to us.
  if not mat = input.match(/\A#{o[:enabled_as]}\.((?:[^.].*)|)\z/)
    return nil
  end

  lookup = mat[1]

  # Parse lookup string into node name and prefix.
  global_name, prefix = if mat = lookup.match(/\A(?:([^.]*)|(.+)\.(.*?))\z/)
    if mat[1]
      # "something".
      ["", mat[1]]
    else
      # "something.other", "something.other.other.".
      [mat[2], mat[3]]
    end
  else
    # Handle no match just in case.
    ["", ""]
  end

  base = if global_name == ""
    # Base is root.
    nil
  else
    # Find a named base node. If not found, return no candidates right away.
    find_node(global_name) or return []
  end
  
  # Select sub-nodes.
  candidates = children_of(base).select do |node|
    # Select those matching `prefix`.
    node.name.to_s.index(prefix) == 0
  end.map do |node|
    # Provide 1+ candidates per item.
    case node
    when Node::Group
      # A neat trick to prevent IRB from appending a " " after group name.
      [node.name, "#{node.name}."]
    else
      [node.name]
    end.map(&:to_s)
  end.flatten(1).map do |s|
    # Convert to final names.
    [
      "#{o[:enabled_as]}.",
      ("#{global_name}." if global_name != ""),
      s,
    ].compact.join
  end

  candidates
end

#define(&block) ⇒ Object

Define groups/hacks via the DSL. See HackTree::define for examples.



123
124
125
126
127
# File 'lib/hack_tree/instance.rb', line 123

def define(&block)
  raise "Code block expected" if not block
  DslContext.new(self).instance_eval(&block)
  nil
end

#find_local_node(name, parent) ⇒ Object

Search for a local node, return Node::* or nil.

find_node(:hello)                   # Search at root.
find_node(:hello, :parent => grp)   # Search in `grp` group.

See also: #find_node.



145
146
147
# File 'lib/hack_tree/instance.rb', line 145

def find_local_node(name, parent)
  @nodes.find {|r| r.name == name.to_sym and r.parent == parent}
end

#find_node(global_name) ⇒ Object

Search for the node by its global name, return Node::* or nil.

find_node("hello")            # => Node::* or nil
find_node("do.some.stuff")    # => Node::* or nil

See also: #find_local_node.



135
136
137
# File 'lib/hack_tree/instance.rb', line 135

def find_node(global_name)
  @nodes.find {|node| node.global_name == global_name}
end