Class: O
- Inherits:
-
Hash
- Object
- Hash
- O
- Includes:
- HashMethodFix, Semantics
- Defined in:
- lib/o1.rb,
lib/o.rb,
lib/o/parser.rb,
lib/o/version.rb,
lib/o/semantics.rb,
lib/o/hash_method_fix.rb
Overview
internal: store data in a Hash, the key of the Hash is always converted to symbol.
Defined Under Namespace
Modules: HashMethodFix, Semantics, VERSION Classes: O_Eval, Parser
Constant Summary collapse
- Error =
Exception.new
- LoadError =
Exception.new(Error)
- BUILTIN_METHODS =
[ :p, :pd, :raise, :sleep, :rand, :srand, :exit, :require, :at_exit, :autoload, :open]
- PATH =
PATH for O.load
[]
Instance Attribute Summary collapse
-
#_child ⇒ Object
Returns the value of attribute _child.
-
#_data ⇒ Object
readonly
Returns the value of attribute _data.
-
#_parent ⇒ Object
Returns the value of attribute _parent.
-
#_root ⇒ Object
Returns the value of attribute _root.
Class Method Summary collapse
-
.[](data) ⇒ Object
convert hash, O to O.
- .eval(content = nil, &blk) ⇒ Object
-
.from_hash(hash) ⇒ Object
convert <#Hash> to <#O>.
-
.get(obj) ⇒ Hash
get hash data from obj.
-
.load(name) ⇒ O
load a configuration file, support PATH, and ‘~/.gutenrc’.
-
.relative_load(name) ⇒ O
relative load a configuration file.
-
.require(name) ⇒ O
load a configuration file, use $: and support ‘~/.gutenrc’.
Instance Method Summary collapse
- #+(other) ⇒ Object
- #==(other) ⇒ Object
- #[](key) ⇒ Object
- #[]=(key, value) ⇒ Object
-
#_blk2method(&blk) ⇒ Object
convert block to method.
- #_dup ⇒ Object
- #_replace(data) ⇒ Object
- #_temp(&blk) ⇒ Object
-
#initialize(default = nil, &blk) ⇒ O
constructor
A new instance of O.
-
#inspect ⇒ Object
(also: #to_s)
<#O :b => 1 :c => 2 :d => <#O :c => 2>>.
- #method_missing(method, *args, &blk) ⇒ Object
Methods included from HashMethodFix
Methods included from Semantics
Constructor Details
#initialize(default = nil, &blk) ⇒ O
Returns a new instance of O.
104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/o.rb', line 104 def initialize default=nil, ={}, &blk @_root = [:_root] @_child = Hash.new(default) if blk method = _blk2method(&blk) if blk.arity == 0 method.call else method.call self end end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args, &blk) ⇒ Object
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 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 |
# File 'lib/o.rb', line 191 def method_missing name, *args, &blk #O.pd 'missing', name, args, blk # path: root if name == :_ return _root # relative path. elsif name =~ /^__+$/ num = name.to_s.count('_') - 1 node = self num.times { return unless node node = node._parent } return node # .name= elsif name =~ /(.*)=$/ return @_child[$1.to_sym] = args[0] # .name? elsif name =~ /(.*)\?$/ return !! @_child[$1.to_sym] # ._name elsif name =~ /^_(.*)/ name = $1.to_sym args.map!{|arg| O===arg ? arg._child : arg} return @_child.send(name, *args, &blk) elsif Proc === @_child[name] return @_child[name].call *args # a.c # return data if has :c # a.c # create new <#O> if no :c # elsif args.empty? # a.b.c 1 # a.b do # c 2 # end if @_child.has_key?(name) o = @_child[name] o.instance_eval(&blk) if blk return o else next_o = O.new(nil, {_root: _root}) next_o._parent = self self._child[name] = next_o next_o.instance_eval(&blk) if blk return next_o end # .name value else @_child[name] = args[0] return args[0] end end |
Instance Attribute Details
#_child ⇒ Object
Returns the value of attribute _child.
102 103 104 |
# File 'lib/o.rb', line 102 def _child @_child end |
#_data ⇒ Object (readonly)
Returns the value of attribute _data.
114 115 116 |
# File 'lib/o1.rb', line 114 def _data @_data end |
#_parent ⇒ Object
Returns the value of attribute _parent.
102 103 104 |
# File 'lib/o.rb', line 102 def _parent @_parent end |
#_root ⇒ Object
Returns the value of attribute _root.
102 103 104 |
# File 'lib/o.rb', line 102 def _root @_root end |
Class Method Details
.[](data) ⇒ Object
convert hash, O to O
26 27 28 29 30 31 32 33 34 35 |
# File 'lib/o.rb', line 26 def [] data case data when O data when Hash o = O.new o._child = data o end end |
.eval(content = nil, &blk) ⇒ Object
18 19 20 21 22 |
# File 'lib/o.rb', line 18 def eval content=nil, &blk o = O.new nil content ? o.instance_eval(Parser.compile(content)) : o.instance_eval(&blk) o._root end |
.from_hash(hash) ⇒ Object
convert <#Hash> to <#O>
31 32 33 34 |
# File 'lib/o1.rb', line 31 def from_hash hash o = O.new o._replace hash end |
.get(obj) ⇒ Hash
get hash data from obj
42 43 44 45 46 47 48 49 |
# File 'lib/o.rb', line 42 def get obj case obj when Hash obj when O obj._child end end |
.load(name) ⇒ O
load a configuration file, support PATH, and ‘~/.gutenrc’
first try name.rb, then use name
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/o1.rb', line 52 def load name path = nil if name =~ /^~/ file = File.(name) path = file if File.exists?(file) elsif File.absolute_path(name) == name path = name if File.exists?(name) else catch :break do PATH.each do |p| ['.rb', ''].each {|ext| file = File.join(p, name+ext) if File.exists? file path = file throw :break end } end end end raise LoadError, "can't find file -- #{name}" unless path eval_file path end |
.relative_load(name) ⇒ O
relative load a configuration file
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/o1.rb', line 83 def relative_load name pd caller if $TEST a,file, line, method = caller[0].match(/^(.*):(\d+):.*`(.*)'$/).to_a raise LoadError, "#{type} is called in #{file}" if file=~/\(.*\)/ # eval, etc. file = File.readlink(file) if File.symlink?(file) path = nil [".rb", ""].each do |ext| f = File.absolute_path(File.join(File.dirname(file), name+ext)) if File.exists?(f) path = f break end end raise LoadError, "can't find file -- #{name}" unless path eval_file path end |
.require(name) ⇒ O
load a configuration file, use $: and support ‘~/.gutenrc’
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 |
# File 'lib/o.rb', line 65 def require name path = nil # ~/.gutenrc if name =~ /^~/ file = File.(name) path = file if File.exists?(file) # /absolute/path/to/rc elsif File.absolute_path(name) == name path = name if File.exists?(name) # relative/rc else catch :break do $:.each do |p| ['.rb', ''].each {|ext| file = File.join(p, name+ext) if File.exists? file path = file throw :break end } end end end raise LoadError, "can't find file -- #{name}" unless path O.eval File.read(path) end |
Instance Method Details
#+(other) ⇒ Object
161 162 163 164 |
# File 'lib/o.rb', line 161 def + other raise Error, "not support type for + -- #{other.inspect}" unless O === other O.new(_child, other._child) end |
#==(other) ⇒ Object
146 147 148 |
# File 'lib/o.rb', line 146 def == other _child == other._child end |
#[](key) ⇒ Object
141 142 143 144 |
# File 'lib/o.rb', line 141 def [] key key = key.respond_to?(:to_sym) ? key.to_sym : key @_child[key] end |
#[]=(key, value) ⇒ Object
136 137 138 139 |
# File 'lib/o.rb', line 136 def []= key, value key = key.respond_to?(:to_sym) ? key.to_sym : key @_child[key] = value end |
#_blk2method(&blk) ⇒ Object
convert block to method.
you can call a block with arguments
174 175 176 177 178 179 |
# File 'lib/o.rb', line 174 def _blk2method &blk self.class.class_eval do define_method(:__blk2method, &blk) end method(:__blk2method) end |
#_dup ⇒ Object
150 151 152 153 154 |
# File 'lib/o.rb', line 150 def _dup o = O.new o._child = _child.dup o end |
#_replace(data) ⇒ Object
156 157 158 159 |
# File 'lib/o.rb', line 156 def _replace obj self._child = O.get(obj) self end |
#_temp(&blk) ⇒ Object
118 119 120 121 122 |
# File 'lib/o.rb', line 118 def _temp &blk data = _child.dup blk.call self._child = data end |
#inspect ⇒ Object Also known as: to_s
<#O
:b => 1
:c => 2
:d => <#O
:c => 2>>
260 261 262 263 264 265 266 267 268 |
# File 'lib/o.rb', line 260 def inspect(indent=" ") o={rst: ""} o[:rst] << "<#O\n" _child.each do |k,v| o[:rst] << "#{indent}#{k.inspect} => " o[:rst] << (O === v ? "#{v.inspect(indent+" ")}\n" : "#{v.inspect}\n") end o[:rst].rstrip! << ">" end |