Class: O

Inherits:
Object
  • Object
show all
Includes:
HashMethodFix, Semantics
Defined in:
lib/o.rb,
lib/o/parser.rb,
lib/o/version.rb,
lib/o/semantics.rb,
lib/o/hash_method_fix.rb

Defined Under Namespace

Modules: HashMethodFix, Semantics, VERSION Classes: Parser

Constant Summary collapse

Error =
Class.new Exception
LoadError =
Class.new Error
BUILTIN_METHODS =
[ :p, :raise, :sleep, :rand, :srand, :exit, :require, :at_exit, :autoload, :open]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from HashMethodFix

#_merge, #_merge!

Methods included from Semantics

#no, #yes

Constructor Details

#initialize(default = nil, options = {}, &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, options={}, &blk
	@_root = options[:_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(name, *args, &blk) ⇒ Object

.name? .name= value .name value ._name

.c .a.b.c



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.p d '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

#_childObject

Returns the value of attribute _child.



102
103
104
# File 'lib/o.rb', line 102

def _child
  @_child
end

#_parentObject

Returns the value of attribute _parent.



102
103
104
# File 'lib/o.rb', line 102

def _parent
  @_parent
end

#_rootObject

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

Parameters:

  • data (O, Hash)


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

.get(obj) ⇒ Hash

get hash data from obj

Parameters:

  • obj (O, Hash)

Returns:

  • (Hash)


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

.require(name) ⇒ O

load a configuration file, use $: and support ‘~/.gutenrc’

Examples:

option = O.load("~/.gutenrc")

option = O.load("/absolute/path/a.rb")

O::Path << "/home"
option = O.load("guten")  #=> try "guten.rb"; then try "guten"
option = O.load("guten.rb")

Parameters:

  • name (String)

Returns:

  • (O)

Raises:



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.expand_path(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

Raises:



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

Examples:

USAGE

instance_eval(&blk)
blk2method(&blk).call *args


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

#_dupObject



150
151
152
153
154
# File 'lib/o.rb', line 150

def _dup
	o = O.new
	o._child = _child.dup
	o
end

#_replace(obj) ⇒ 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(indent = " ") ⇒ 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