openobject 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +190 -0
- data/README.erb +35 -0
- data/Rakefile +371 -0
- data/install.rb +210 -0
- data/lib/openobject.rb +119 -0
- data/openobject.gemspec +27 -0
- data/sample/a.rb +9 -0
- data/sample/b.rb +8 -0
- data/sample/c.rb +16 -0
- data/sample/d.rb +10 -0
- data/sample/e.rb +6 -0
- data/sample/f.rb +39 -0
- metadata +87 -0
data/README
ADDED
@@ -0,0 +1,190 @@
|
|
1
|
+
NAME
|
2
|
+
|
3
|
+
openobject
|
4
|
+
|
5
|
+
SYNOPSIS
|
6
|
+
|
7
|
+
a simple property based container that's much more capable than a blankslate
|
8
|
+
but far less polluted than ruby's built-in OpenStruct. openobject is a tiny
|
9
|
+
lib that couples the power of the 'fattr' gem alongside a slightly
|
10
|
+
enhanced blankslate type object.
|
11
|
+
|
12
|
+
INSTALL
|
13
|
+
|
14
|
+
gem install openobject
|
15
|
+
|
16
|
+
URIS
|
17
|
+
|
18
|
+
http://codeforpeople.com/lib/ruby/
|
19
|
+
http://rubyforge.org/projects/codeforpeople/
|
20
|
+
|
21
|
+
HISTORY
|
22
|
+
|
23
|
+
1.0.0
|
24
|
+
github import
|
25
|
+
|
26
|
+
0.0.3
|
27
|
+
added support for default values
|
28
|
+
|
29
|
+
SAMPLES
|
30
|
+
|
31
|
+
|
32
|
+
<========< sample/a.rb >========>
|
33
|
+
|
34
|
+
~ > cat sample/a.rb
|
35
|
+
|
36
|
+
require 'openobject'
|
37
|
+
|
38
|
+
oo = openobject
|
39
|
+
|
40
|
+
oo.foo = 42
|
41
|
+
oo.bar 'forty-two'
|
42
|
+
|
43
|
+
p oo.foo
|
44
|
+
p oo.bar
|
45
|
+
|
46
|
+
~ > ruby sample/a.rb
|
47
|
+
|
48
|
+
42
|
49
|
+
"forty-two"
|
50
|
+
|
51
|
+
|
52
|
+
<========< sample/b.rb >========>
|
53
|
+
|
54
|
+
~ > cat sample/b.rb
|
55
|
+
|
56
|
+
require 'openobject'
|
57
|
+
|
58
|
+
oo = openobject :foo => 42, :bar => 'forty-two' do
|
59
|
+
foobar 42.0
|
60
|
+
end
|
61
|
+
|
62
|
+
p oo.to_hash
|
63
|
+
p oo.fattrs
|
64
|
+
|
65
|
+
~ > ruby sample/b.rb
|
66
|
+
|
67
|
+
{"foobar"=>42.0, "foo"=>42, "bar"=>"forty-two"}
|
68
|
+
["foo", "bar", "foobar"]
|
69
|
+
|
70
|
+
|
71
|
+
<========< sample/c.rb >========>
|
72
|
+
|
73
|
+
~ > cat sample/c.rb
|
74
|
+
|
75
|
+
require 'openobject'
|
76
|
+
|
77
|
+
oo = openobject :foo => 42
|
78
|
+
|
79
|
+
oo.bar = 'forty-two'
|
80
|
+
|
81
|
+
oo.extend do
|
82
|
+
fattr :foobar => 42.0
|
83
|
+
|
84
|
+
def barfoo
|
85
|
+
[ foo, bar, foobar ]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
p oo.foobar
|
90
|
+
p oo.barfoo
|
91
|
+
|
92
|
+
~ > ruby sample/c.rb
|
93
|
+
|
94
|
+
42.0
|
95
|
+
[42, "forty-two", 42.0]
|
96
|
+
|
97
|
+
|
98
|
+
<========< sample/d.rb >========>
|
99
|
+
|
100
|
+
~ > cat sample/d.rb
|
101
|
+
|
102
|
+
require 'openobject'
|
103
|
+
|
104
|
+
config =
|
105
|
+
oo{
|
106
|
+
header oo(:width => 42, :height => 42)
|
107
|
+
footer oo{ width 42.0; height 42.0 }
|
108
|
+
}
|
109
|
+
|
110
|
+
p config.header.width
|
111
|
+
p config.footer.height
|
112
|
+
|
113
|
+
~ > ruby sample/d.rb
|
114
|
+
|
115
|
+
42
|
116
|
+
42.0
|
117
|
+
|
118
|
+
|
119
|
+
<========< sample/e.rb >========>
|
120
|
+
|
121
|
+
~ > cat sample/e.rb
|
122
|
+
|
123
|
+
require 'openobject'
|
124
|
+
|
125
|
+
css = oo
|
126
|
+
|
127
|
+
css.class = 'subtle'
|
128
|
+
css.style = 'display:none'
|
129
|
+
|
130
|
+
~ > ruby sample/e.rb
|
131
|
+
|
132
|
+
|
133
|
+
|
134
|
+
<========< sample/f.rb >========>
|
135
|
+
|
136
|
+
~ > cat sample/f.rb
|
137
|
+
|
138
|
+
require 'openobject'
|
139
|
+
|
140
|
+
# by default you cannot retrive unset values
|
141
|
+
#
|
142
|
+
o = oo
|
143
|
+
begin; o.foo; rescue NameError; p NameError; end
|
144
|
+
|
145
|
+
#=> NameError
|
146
|
+
|
147
|
+
# but you can set anything
|
148
|
+
#
|
149
|
+
o = oo
|
150
|
+
o.foo = 42
|
151
|
+
p o.foo
|
152
|
+
|
153
|
+
#=> 42
|
154
|
+
|
155
|
+
# blocks can extend openobjects
|
156
|
+
#
|
157
|
+
o = oo{ def bar() 42 end }
|
158
|
+
p o.bar
|
159
|
+
|
160
|
+
#=> 42
|
161
|
+
|
162
|
+
# you can set a default value which will be returned for anything
|
163
|
+
# missing value
|
164
|
+
#
|
165
|
+
o = oo{ default 42 }
|
166
|
+
p o.bar
|
167
|
+
|
168
|
+
#=> 42
|
169
|
+
|
170
|
+
# and the default value itself can be someting block/proc-like
|
171
|
+
#
|
172
|
+
n = 40
|
173
|
+
o = oo{ default{ n += 2 } }
|
174
|
+
p o.foo
|
175
|
+
|
176
|
+
#=> 42
|
177
|
+
|
178
|
+
~ > ruby sample/f.rb
|
179
|
+
|
180
|
+
NameError
|
181
|
+
42
|
182
|
+
42
|
183
|
+
42
|
184
|
+
42
|
185
|
+
|
186
|
+
|
187
|
+
|
188
|
+
AUTHOR
|
189
|
+
|
190
|
+
ara.t.howard@gmail.com
|
data/README.erb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
NAME
|
2
|
+
|
3
|
+
openobject
|
4
|
+
|
5
|
+
SYNOPSIS
|
6
|
+
|
7
|
+
a simple property based container that's much more capable than a blankslate
|
8
|
+
but far less polluted than ruby's built-in OpenStruct. openobject is a tiny
|
9
|
+
lib that couples the power of the 'fattr' gem alongside a slightly
|
10
|
+
enhanced blankslate type object.
|
11
|
+
|
12
|
+
INSTALL
|
13
|
+
|
14
|
+
gem install openobject
|
15
|
+
|
16
|
+
URIS
|
17
|
+
|
18
|
+
http://codeforpeople.com/lib/ruby/
|
19
|
+
http://rubyforge.org/projects/codeforpeople/
|
20
|
+
|
21
|
+
HISTORY
|
22
|
+
|
23
|
+
1.0.0
|
24
|
+
github import
|
25
|
+
|
26
|
+
0.0.3
|
27
|
+
added support for default values
|
28
|
+
|
29
|
+
SAMPLES
|
30
|
+
|
31
|
+
<%= samples %>
|
32
|
+
|
33
|
+
AUTHOR
|
34
|
+
|
35
|
+
ara.t.howard@gmail.com
|
data/Rakefile
ADDED
@@ -0,0 +1,371 @@
|
|
1
|
+
This.rubyforge_project = 'codeforpeople'
|
2
|
+
This.author = "Ara T. Howard"
|
3
|
+
This.email = "ara.t.howard@gmail.com"
|
4
|
+
This.homepage = "http://github.com/ahoward/#{ This.lib }/tree/master"
|
5
|
+
|
6
|
+
|
7
|
+
task :default do
|
8
|
+
puts((Rake::Task.tasks.map{|task| task.name.gsub(/::/,':')} - ['default']).sort)
|
9
|
+
end
|
10
|
+
|
11
|
+
task :test do
|
12
|
+
run_tests!
|
13
|
+
end
|
14
|
+
|
15
|
+
namespace :test do
|
16
|
+
task(:unit){ run_tests!(:unit) }
|
17
|
+
task(:functional){ run_tests!(:functional) }
|
18
|
+
task(:integration){ run_tests!(:integration) }
|
19
|
+
end
|
20
|
+
|
21
|
+
def run_tests!(which = nil)
|
22
|
+
which ||= '**'
|
23
|
+
test_dir = File.join(This.dir, "test")
|
24
|
+
test_glob ||= File.join(test_dir, "#{ which }/**_test.rb")
|
25
|
+
test_rbs = Dir.glob(test_glob).sort
|
26
|
+
|
27
|
+
div = ('=' * 119)
|
28
|
+
line = ('-' * 119)
|
29
|
+
helper = "-r ./test/helper.rb" if test(?e, "./test/helper.rb")
|
30
|
+
|
31
|
+
test_rbs.each_with_index do |test_rb, index|
|
32
|
+
testno = index + 1
|
33
|
+
command = "#{ This.ruby } -I ./lib -I ./test/lib #{ helper } #{ test_rb }"
|
34
|
+
|
35
|
+
puts
|
36
|
+
say(div, :color => :cyan, :bold => true)
|
37
|
+
say("@#{ testno } => ", :bold => true, :method => :print)
|
38
|
+
say(command, :color => :cyan, :bold => true)
|
39
|
+
say(line, :color => :cyan, :bold => true)
|
40
|
+
|
41
|
+
system(command)
|
42
|
+
|
43
|
+
say(line, :color => :cyan, :bold => true)
|
44
|
+
|
45
|
+
status = $?.exitstatus
|
46
|
+
|
47
|
+
if status.zero?
|
48
|
+
say("@#{ testno } <= ", :bold => true, :color => :white, :method => :print)
|
49
|
+
say("SUCCESS", :color => :green, :bold => true)
|
50
|
+
else
|
51
|
+
say("@#{ testno } <= ", :bold => true, :color => :white, :method => :print)
|
52
|
+
say("FAILURE", :color => :red, :bold => true)
|
53
|
+
end
|
54
|
+
say(line, :color => :cyan, :bold => true)
|
55
|
+
|
56
|
+
exit(status) unless status.zero?
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
task :gemspec do
|
62
|
+
ignore_extensions = 'git', 'svn', 'tmp', /sw./, 'bak', 'gem'
|
63
|
+
ignore_directories = 'pkg'
|
64
|
+
ignore_files = 'test/log'
|
65
|
+
|
66
|
+
shiteless =
|
67
|
+
lambda do |list|
|
68
|
+
list.delete_if do |entry|
|
69
|
+
next unless test(?e, entry)
|
70
|
+
extension = File.basename(entry).split(%r/[.]/).last
|
71
|
+
ignore_extensions.any?{|ext| ext === extension}
|
72
|
+
end
|
73
|
+
list.delete_if do |entry|
|
74
|
+
next unless test(?d, entry)
|
75
|
+
dirname = File.expand_path(entry)
|
76
|
+
ignore_directories.any?{|dir| File.expand_path(dir) == dirname}
|
77
|
+
end
|
78
|
+
list.delete_if do |entry|
|
79
|
+
next unless test(?f, entry)
|
80
|
+
filename = File.expand_path(entry)
|
81
|
+
ignore_files.any?{|file| File.expand_path(file) == filename}
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
lib = This.lib
|
86
|
+
object = This.object
|
87
|
+
version = This.version
|
88
|
+
files = shiteless[Dir::glob("**/**")]
|
89
|
+
executables = shiteless[Dir::glob("bin/*")].map{|exe| File.basename(exe)}
|
90
|
+
has_rdoc = true #File.exist?('doc')
|
91
|
+
test_files = "test/#{ lib }.rb" if File.file?("test/#{ lib }.rb")
|
92
|
+
summary = object.respond_to?(:summary) ? object.summary : "summary: #{ lib } kicks the ass"
|
93
|
+
description = object.respond_to?(:description) ? object.description : "description: #{ lib } kicks the ass"
|
94
|
+
|
95
|
+
if This.extensions.nil?
|
96
|
+
This.extensions = []
|
97
|
+
extensions = This.extensions
|
98
|
+
%w( Makefile configure extconf.rb ).each do |ext|
|
99
|
+
extensions << ext if File.exists?(ext)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
extensions = [extensions].flatten.compact
|
103
|
+
|
104
|
+
template =
|
105
|
+
if test(?e, 'gemspec.erb')
|
106
|
+
Template{ IO.read('gemspec.erb') }
|
107
|
+
else
|
108
|
+
Template {
|
109
|
+
<<-__
|
110
|
+
## #{ lib }.gemspec
|
111
|
+
#
|
112
|
+
|
113
|
+
Gem::Specification::new do |spec|
|
114
|
+
spec.name = #{ lib.inspect }
|
115
|
+
spec.version = #{ version.inspect }
|
116
|
+
spec.platform = Gem::Platform::RUBY
|
117
|
+
spec.summary = #{ lib.inspect }
|
118
|
+
spec.description = #{ description.inspect }
|
119
|
+
|
120
|
+
spec.files = #{ files.inspect }
|
121
|
+
spec.executables = #{ executables.inspect }
|
122
|
+
|
123
|
+
spec.require_path = "lib"
|
124
|
+
|
125
|
+
spec.has_rdoc = #{ has_rdoc.inspect }
|
126
|
+
spec.test_files = #{ test_files.inspect }
|
127
|
+
#spec.add_dependency 'lib', '>= version'
|
128
|
+
spec.add_dependency 'fattr'
|
129
|
+
|
130
|
+
spec.extensions.push(*#{ extensions.inspect })
|
131
|
+
|
132
|
+
spec.rubyforge_project = #{ This.rubyforge_project.inspect }
|
133
|
+
spec.author = #{ This.author.inspect }
|
134
|
+
spec.email = #{ This.email.inspect }
|
135
|
+
spec.homepage = #{ This.homepage.inspect }
|
136
|
+
end
|
137
|
+
__
|
138
|
+
}
|
139
|
+
end
|
140
|
+
|
141
|
+
Fu.mkdir_p(This.pkgdir)
|
142
|
+
gemspec = File.join(This.pkgdir, "#{ lib }.gemspec")
|
143
|
+
open(gemspec, "w"){|fd| fd.puts(template)}
|
144
|
+
This.gemspec = gemspec
|
145
|
+
end
|
146
|
+
|
147
|
+
task :gem => [:clean, :gemspec] do
|
148
|
+
Fu.mkdir_p(This.pkgdir)
|
149
|
+
before = Dir['*.gem']
|
150
|
+
cmd = "gem build #{ This.gemspec }"
|
151
|
+
`#{ cmd }`
|
152
|
+
after = Dir['*.gem']
|
153
|
+
gem = ((after - before).first || after.first) or abort('no gem!')
|
154
|
+
Fu.mv(gem, This.pkgdir)
|
155
|
+
This.gem = File.join(This.pkgdir, File.basename(gem))
|
156
|
+
end
|
157
|
+
|
158
|
+
task :readme do
|
159
|
+
samples = ''
|
160
|
+
prompt = '~ > '
|
161
|
+
lib = This.lib
|
162
|
+
version = This.version
|
163
|
+
|
164
|
+
Dir['sample*/*'].sort.each do |sample|
|
165
|
+
samples << "\n" << " <========< #{ sample } >========>" << "\n\n"
|
166
|
+
|
167
|
+
cmd = "cat #{ sample }"
|
168
|
+
samples << Util.indent(prompt + cmd, 2) << "\n\n"
|
169
|
+
samples << Util.indent(`#{ cmd }`, 4) << "\n"
|
170
|
+
|
171
|
+
cmd = "ruby #{ sample }"
|
172
|
+
samples << Util.indent(prompt + cmd, 2) << "\n\n"
|
173
|
+
|
174
|
+
cmd = "ruby -e'STDOUT.sync=true; exec %(ruby -I ./lib #{ sample })'"
|
175
|
+
samples << Util.indent(`#{ cmd } 2>&1`, 4) << "\n"
|
176
|
+
end
|
177
|
+
|
178
|
+
template =
|
179
|
+
if test(?e, 'readme.erb')
|
180
|
+
Template{ IO.read('readme.erb') }
|
181
|
+
else
|
182
|
+
Template {
|
183
|
+
<<-__
|
184
|
+
NAME
|
185
|
+
#{ lib }
|
186
|
+
|
187
|
+
DESCRIPTION
|
188
|
+
|
189
|
+
INSTALL
|
190
|
+
gem install #{ lib }
|
191
|
+
|
192
|
+
SAMPLES
|
193
|
+
#{ samples }
|
194
|
+
__
|
195
|
+
}
|
196
|
+
end
|
197
|
+
|
198
|
+
open("README", "w"){|fd| fd.puts template}
|
199
|
+
end
|
200
|
+
|
201
|
+
|
202
|
+
task :clean do
|
203
|
+
Dir[File.join(This.pkgdir, '**/**')].each{|entry| Fu.rm_rf(entry)}
|
204
|
+
end
|
205
|
+
|
206
|
+
|
207
|
+
task :release => [:clean, :gemspec, :gem] do
|
208
|
+
gems = Dir[File.join(This.pkgdir, '*.gem')].flatten
|
209
|
+
raise "which one? : #{ gems.inspect }" if gems.size > 1
|
210
|
+
raise "no gems?" if gems.size < 1
|
211
|
+
|
212
|
+
cmd = "gem push #{ This.gem }"
|
213
|
+
puts cmd
|
214
|
+
puts
|
215
|
+
system(cmd)
|
216
|
+
abort("cmd(#{ cmd }) failed with (#{ $?.inspect })") unless $?.exitstatus.zero?
|
217
|
+
|
218
|
+
cmd = "rubyforge login && rubyforge add_release #{ This.rubyforge_project } #{ This.lib } #{ This.version } #{ This.gem }"
|
219
|
+
puts cmd
|
220
|
+
puts
|
221
|
+
system(cmd)
|
222
|
+
abort("cmd(#{ cmd }) failed with (#{ $?.inspect })") unless $?.exitstatus.zero?
|
223
|
+
end
|
224
|
+
|
225
|
+
|
226
|
+
|
227
|
+
|
228
|
+
|
229
|
+
BEGIN {
|
230
|
+
# support for this rakefile
|
231
|
+
#
|
232
|
+
$VERBOSE = nil
|
233
|
+
|
234
|
+
require 'ostruct'
|
235
|
+
require 'erb'
|
236
|
+
require 'fileutils'
|
237
|
+
require 'rbconfig'
|
238
|
+
|
239
|
+
# fu shortcut
|
240
|
+
#
|
241
|
+
Fu = FileUtils
|
242
|
+
|
243
|
+
# cache a bunch of stuff about this rakefile/environment
|
244
|
+
#
|
245
|
+
This = OpenStruct.new
|
246
|
+
|
247
|
+
This.file = File.expand_path(__FILE__)
|
248
|
+
This.dir = File.dirname(This.file)
|
249
|
+
This.pkgdir = File.join(This.dir, 'pkg')
|
250
|
+
|
251
|
+
# grok lib
|
252
|
+
#
|
253
|
+
lib = ENV['LIB']
|
254
|
+
unless lib
|
255
|
+
lib = File.basename(Dir.pwd).sub(/[-].*$/, '')
|
256
|
+
end
|
257
|
+
This.lib = lib
|
258
|
+
|
259
|
+
# grok version
|
260
|
+
#
|
261
|
+
version = ENV['VERSION']
|
262
|
+
unless version
|
263
|
+
require "./lib/#{ This.lib }"
|
264
|
+
This.name = lib.capitalize
|
265
|
+
This.object = eval(This.name)
|
266
|
+
version = This.object.send(:version)
|
267
|
+
end
|
268
|
+
This.version = version
|
269
|
+
|
270
|
+
# we need to know the name of the lib an it's version
|
271
|
+
#
|
272
|
+
abort('no lib') unless This.lib
|
273
|
+
abort('no version') unless This.version
|
274
|
+
|
275
|
+
# discover full path to this ruby executable
|
276
|
+
#
|
277
|
+
c = Config::CONFIG
|
278
|
+
bindir = c["bindir"] || c['BINDIR']
|
279
|
+
ruby_install_name = c['ruby_install_name'] || c['RUBY_INSTALL_NAME'] || 'ruby'
|
280
|
+
ruby_ext = c['EXEEXT'] || ''
|
281
|
+
ruby = File.join(bindir, (ruby_install_name + ruby_ext))
|
282
|
+
This.ruby = ruby
|
283
|
+
|
284
|
+
# some utils
|
285
|
+
#
|
286
|
+
module Util
|
287
|
+
def indent(s, n = 2)
|
288
|
+
s = unindent(s)
|
289
|
+
ws = ' ' * n
|
290
|
+
s.gsub(%r/^/, ws)
|
291
|
+
end
|
292
|
+
|
293
|
+
def unindent(s)
|
294
|
+
indent = nil
|
295
|
+
s.each do |line|
|
296
|
+
next if line =~ %r/^\s*$/
|
297
|
+
indent = line[%r/^\s*/] and break
|
298
|
+
end
|
299
|
+
indent ? s.gsub(%r/^#{ indent }/, "") : s
|
300
|
+
end
|
301
|
+
extend self
|
302
|
+
end
|
303
|
+
|
304
|
+
# template support
|
305
|
+
#
|
306
|
+
class Template
|
307
|
+
def initialize(&block)
|
308
|
+
@block = block
|
309
|
+
@template = block.call.to_s
|
310
|
+
end
|
311
|
+
def expand(b=nil)
|
312
|
+
ERB.new(Util.unindent(@template)).result(b||@block)
|
313
|
+
end
|
314
|
+
alias_method 'to_s', 'expand'
|
315
|
+
end
|
316
|
+
def Template(*args, &block) Template.new(*args, &block) end
|
317
|
+
|
318
|
+
# colored console output support
|
319
|
+
#
|
320
|
+
This.ansi = {
|
321
|
+
:clear => "\e[0m",
|
322
|
+
:reset => "\e[0m",
|
323
|
+
:erase_line => "\e[K",
|
324
|
+
:erase_char => "\e[P",
|
325
|
+
:bold => "\e[1m",
|
326
|
+
:dark => "\e[2m",
|
327
|
+
:underline => "\e[4m",
|
328
|
+
:underscore => "\e[4m",
|
329
|
+
:blink => "\e[5m",
|
330
|
+
:reverse => "\e[7m",
|
331
|
+
:concealed => "\e[8m",
|
332
|
+
:black => "\e[30m",
|
333
|
+
:red => "\e[31m",
|
334
|
+
:green => "\e[32m",
|
335
|
+
:yellow => "\e[33m",
|
336
|
+
:blue => "\e[34m",
|
337
|
+
:magenta => "\e[35m",
|
338
|
+
:cyan => "\e[36m",
|
339
|
+
:white => "\e[37m",
|
340
|
+
:on_black => "\e[40m",
|
341
|
+
:on_red => "\e[41m",
|
342
|
+
:on_green => "\e[42m",
|
343
|
+
:on_yellow => "\e[43m",
|
344
|
+
:on_blue => "\e[44m",
|
345
|
+
:on_magenta => "\e[45m",
|
346
|
+
:on_cyan => "\e[46m",
|
347
|
+
:on_white => "\e[47m"
|
348
|
+
}
|
349
|
+
def say(phrase, *args)
|
350
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
351
|
+
options[:color] = args.shift.to_s.to_sym unless args.empty?
|
352
|
+
keys = options.keys
|
353
|
+
keys.each{|key| options[key.to_s.to_sym] = options.delete(key)}
|
354
|
+
|
355
|
+
color = options[:color]
|
356
|
+
bold = options.has_key?(:bold)
|
357
|
+
|
358
|
+
parts = [phrase]
|
359
|
+
parts.unshift(This.ansi[color]) if color
|
360
|
+
parts.unshift(This.ansi[:bold]) if bold
|
361
|
+
parts.push(This.ansi[:clear]) if parts.size > 1
|
362
|
+
|
363
|
+
method = options[:method] || :puts
|
364
|
+
|
365
|
+
Kernel.send(method, parts.join)
|
366
|
+
end
|
367
|
+
|
368
|
+
# always run out of the project dir
|
369
|
+
#
|
370
|
+
Dir.chdir(This.dir)
|
371
|
+
}
|
data/install.rb
ADDED
@@ -0,0 +1,210 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rbconfig'
|
3
|
+
require 'find'
|
4
|
+
require 'ftools'
|
5
|
+
require 'tempfile'
|
6
|
+
include Config
|
7
|
+
|
8
|
+
LIBDIR = "lib"
|
9
|
+
LIBDIR_MODE = 0644
|
10
|
+
|
11
|
+
BINDIR = "bin"
|
12
|
+
BINDIR_MODE = 0755
|
13
|
+
|
14
|
+
|
15
|
+
$srcdir = CONFIG["srcdir"]
|
16
|
+
$version = CONFIG["MAJOR"]+"."+CONFIG["MINOR"]
|
17
|
+
$libdir = File.join(CONFIG["libdir"], "ruby", $version)
|
18
|
+
$archdir = File.join($libdir, CONFIG["arch"])
|
19
|
+
$site_libdir = $:.find {|x| x =~ /site_ruby$/}
|
20
|
+
$bindir = CONFIG["bindir"] || CONFIG['BINDIR']
|
21
|
+
$ruby_install_name = CONFIG['ruby_install_name'] || CONFIG['RUBY_INSTALL_NAME'] || 'ruby'
|
22
|
+
$ruby_ext = CONFIG['EXEEXT'] || ''
|
23
|
+
$ruby = File.join($bindir, ($ruby_install_name + $ruby_ext))
|
24
|
+
|
25
|
+
if !$site_libdir
|
26
|
+
$site_libdir = File.join($libdir, "site_ruby")
|
27
|
+
elsif $site_libdir !~ %r/#{Regexp.quote($version)}/
|
28
|
+
$site_libdir = File.join($site_libdir, $version)
|
29
|
+
end
|
30
|
+
|
31
|
+
def install_rb(srcdir=nil, destdir=nil, mode=nil, bin=nil)
|
32
|
+
#{{{
|
33
|
+
path = []
|
34
|
+
dir = []
|
35
|
+
Find.find(srcdir) do |f|
|
36
|
+
next unless FileTest.file?(f)
|
37
|
+
next if (f = f[srcdir.length+1..-1]) == nil
|
38
|
+
next if (/CVS$/ =~ File.dirname(f))
|
39
|
+
next if f =~ %r/\.lnk/
|
40
|
+
path.push f
|
41
|
+
dir |= [File.dirname(f)]
|
42
|
+
end
|
43
|
+
for f in dir
|
44
|
+
next if f == "."
|
45
|
+
next if f == "CVS"
|
46
|
+
File::makedirs(File.join(destdir, f))
|
47
|
+
end
|
48
|
+
for f in path
|
49
|
+
next if (/\~$/ =~ f)
|
50
|
+
next if (/^\./ =~ File.basename(f))
|
51
|
+
unless bin
|
52
|
+
File::install(File.join(srcdir, f), File.join(destdir, f), mode, true)
|
53
|
+
else
|
54
|
+
from = File.join(srcdir, f)
|
55
|
+
to = File.join(destdir, f)
|
56
|
+
shebangify(from) do |sf|
|
57
|
+
$deferr.print from, " -> ", File::catname(from, to), "\n"
|
58
|
+
$deferr.printf "chmod %04o %s\n", mode, to
|
59
|
+
File::install(sf, to, mode, false)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
#}}}
|
64
|
+
end
|
65
|
+
def shebangify f
|
66
|
+
#{{{
|
67
|
+
open(f) do |fd|
|
68
|
+
buf = fd.read 42
|
69
|
+
if buf =~ %r/^\s*#\s*!.*ruby/o
|
70
|
+
ftmp = Tempfile::new("#{ $$ }_#{ File::basename(f) }")
|
71
|
+
begin
|
72
|
+
fd.rewind
|
73
|
+
ftmp.puts "#!#{ $ruby }"
|
74
|
+
while((buf = fd.read(8192)))
|
75
|
+
ftmp.write buf
|
76
|
+
end
|
77
|
+
ftmp.close
|
78
|
+
yield ftmp.path
|
79
|
+
ensure
|
80
|
+
ftmp.close!
|
81
|
+
end
|
82
|
+
else
|
83
|
+
yield f
|
84
|
+
end
|
85
|
+
end
|
86
|
+
#}}}
|
87
|
+
end
|
88
|
+
def ARGV.switch
|
89
|
+
#{{{
|
90
|
+
return nil if self.empty?
|
91
|
+
arg = self.shift
|
92
|
+
return nil if arg == '--'
|
93
|
+
if arg =~ /^-(.)(.*)/
|
94
|
+
return arg if $1 == '-'
|
95
|
+
raise 'unknown switch "-"' if $2.index('-')
|
96
|
+
self.unshift "-#{$2}" if $2.size > 0
|
97
|
+
"-#{$1}"
|
98
|
+
else
|
99
|
+
self.unshift arg
|
100
|
+
nil
|
101
|
+
end
|
102
|
+
#}}}
|
103
|
+
end
|
104
|
+
def ARGV.req_arg
|
105
|
+
#{{{
|
106
|
+
self.shift || raise('missing argument')
|
107
|
+
#}}}
|
108
|
+
end
|
109
|
+
def linkify d, linked = []
|
110
|
+
#--{{{
|
111
|
+
if test ?d, d
|
112
|
+
versioned = Dir[ File::join(d, "*-[0-9].[0-9].[0-9].rb") ]
|
113
|
+
versioned.each do |v|
|
114
|
+
src, dst = v, v.gsub(%r/\-[\d\.]+\.rb$/, '.rb')
|
115
|
+
lnk = nil
|
116
|
+
begin
|
117
|
+
if test ?l, dst
|
118
|
+
lnk = "#{ dst }.lnk"
|
119
|
+
puts "#{ dst } -> #{ lnk }"
|
120
|
+
File::rename dst, lnk
|
121
|
+
end
|
122
|
+
unless test ?e, dst
|
123
|
+
puts "#{ src } -> #{ dst }"
|
124
|
+
File::copy src, dst
|
125
|
+
linked << dst
|
126
|
+
end
|
127
|
+
ensure
|
128
|
+
if lnk
|
129
|
+
at_exit do
|
130
|
+
puts "#{ lnk } -> #{ dst }"
|
131
|
+
File::rename lnk, dst
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
linked
|
138
|
+
#--}}}
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
#
|
143
|
+
# main program
|
144
|
+
#
|
145
|
+
|
146
|
+
libdir = $site_libdir
|
147
|
+
bindir = $bindir
|
148
|
+
no_linkify = false
|
149
|
+
linked = nil
|
150
|
+
help = false
|
151
|
+
|
152
|
+
usage = <<-usage
|
153
|
+
#{ File::basename $0 }
|
154
|
+
-d, --destdir <destdir>
|
155
|
+
-l, --libdir <libdir>
|
156
|
+
-b, --bindir <bindir>
|
157
|
+
-r, --ruby <ruby>
|
158
|
+
-n, --no_linkify
|
159
|
+
-s, --sudo
|
160
|
+
-h, --help
|
161
|
+
usage
|
162
|
+
|
163
|
+
begin
|
164
|
+
while switch = ARGV.switch
|
165
|
+
case switch
|
166
|
+
when '-d', '--destdir'
|
167
|
+
libdir = ARGV.req_arg
|
168
|
+
when '-l', '--libdir'
|
169
|
+
libdir = ARGV.req_arg
|
170
|
+
when '-b', '--bindir'
|
171
|
+
bindir = ARGV.req_arg
|
172
|
+
when '-r', '--ruby'
|
173
|
+
$ruby = ARGV.req_arg
|
174
|
+
when '-n', '--no_linkify'
|
175
|
+
no_linkify = true
|
176
|
+
when '-s', '--sudo'
|
177
|
+
sudo = 'sudo'
|
178
|
+
when '-h', '--help'
|
179
|
+
help = true
|
180
|
+
else
|
181
|
+
raise "unknown switch #{switch.dump}"
|
182
|
+
end
|
183
|
+
end
|
184
|
+
rescue
|
185
|
+
STDERR.puts $!.to_s
|
186
|
+
STDERR.puts usage
|
187
|
+
exit 1
|
188
|
+
end
|
189
|
+
|
190
|
+
if help
|
191
|
+
STDOUT.puts usage
|
192
|
+
exit
|
193
|
+
end
|
194
|
+
|
195
|
+
system "#{ sudo } #{ $ruby } pre-install.rb" if test(?s, 'pre-install.rb')
|
196
|
+
|
197
|
+
unless no_linkify
|
198
|
+
linked = linkify('lib') + linkify('bin')
|
199
|
+
end
|
200
|
+
|
201
|
+
system "#{ $ruby } extconf.rb && make && #{ sudo } make install" if test(?s, 'extconf.rb')
|
202
|
+
|
203
|
+
install_rb(LIBDIR, libdir, LIBDIR_MODE)
|
204
|
+
install_rb(BINDIR, bindir, BINDIR_MODE, bin=true)
|
205
|
+
|
206
|
+
if linked
|
207
|
+
linked.each{|path| File::rm_f path}
|
208
|
+
end
|
209
|
+
|
210
|
+
system "#{ sudo } #{ $ruby } post-install.rb" if test(?s, 'post-install.rb')
|
data/lib/openobject.rb
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'fattr'
|
2
|
+
|
3
|
+
class OpenObject
|
4
|
+
Version = '1.0.0' unless defined?(OpenObject::Version)
|
5
|
+
def OpenObject.version() OpenObject::Version end
|
6
|
+
|
7
|
+
# setup a super blank slate
|
8
|
+
#
|
9
|
+
alias_method "__inspect__", "inspect"
|
10
|
+
alias_method "__to_s__", "to_s"
|
11
|
+
alias_method "__instance_eval__", "instance_eval"
|
12
|
+
|
13
|
+
instance_methods.each{|m| undef_method m unless m[%r/__/]}
|
14
|
+
|
15
|
+
alias_method "instance_eval", "__instance_eval__"
|
16
|
+
alias_method "inspect", "__inspect__"
|
17
|
+
alias_method "to_s", "__to_s__"
|
18
|
+
|
19
|
+
# method missing is contrcuted to raise an error if a property is read that
|
20
|
+
# was never set
|
21
|
+
#
|
22
|
+
def method_missing(m, *a, &b)
|
23
|
+
if(a.empty? and b.nil?)
|
24
|
+
return((
|
25
|
+
if defined?(@default)
|
26
|
+
value = @default.respond_to?(:call) ? @default.call(m, *a) : @default
|
27
|
+
__fattr__(m => value)
|
28
|
+
value
|
29
|
+
else
|
30
|
+
super
|
31
|
+
end
|
32
|
+
))
|
33
|
+
end
|
34
|
+
m = m.to_s
|
35
|
+
setter = m.delete!('=') || a.first || b
|
36
|
+
if setter
|
37
|
+
if a.empty?
|
38
|
+
__fattr__(m, &b)
|
39
|
+
else
|
40
|
+
__fattr__(m => a.shift)
|
41
|
+
end
|
42
|
+
else
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# the default method can be used to force missing attribute calls to return a
|
48
|
+
# value -
|
49
|
+
#
|
50
|
+
def default(*value, &block)
|
51
|
+
@default = (( value.empty? ? block : value.first ))
|
52
|
+
end
|
53
|
+
|
54
|
+
# configure is used to set key/val pairs via a hash AND/OR to to evaluate code
|
55
|
+
# in the instance
|
56
|
+
#
|
57
|
+
def configure(kvs = {}, &b)
|
58
|
+
kvs.each{|k,v| __fattr__(k => v)}
|
59
|
+
__instance_eval__(&b) if b
|
60
|
+
end
|
61
|
+
alias_method "initialize", "configure"
|
62
|
+
alias_method "eval", "configure"
|
63
|
+
|
64
|
+
# return the singleton_class or evaluate code inside of it
|
65
|
+
#
|
66
|
+
def __singleton_class__(&b)
|
67
|
+
sc =
|
68
|
+
class << self
|
69
|
+
self
|
70
|
+
end
|
71
|
+
b ? sc.module_eval(&b) : sc
|
72
|
+
end
|
73
|
+
alias_method "singleton_class", "__singleton_class__"
|
74
|
+
|
75
|
+
# override extend to to the 'normal' thang or extend the instance via a block
|
76
|
+
# of code - evaluated in the singleton class
|
77
|
+
#
|
78
|
+
def extend(*a, &b)
|
79
|
+
if b
|
80
|
+
__singleton_class__(&b)
|
81
|
+
self
|
82
|
+
else
|
83
|
+
super
|
84
|
+
end
|
85
|
+
end
|
86
|
+
alias_method "extending", "extend"
|
87
|
+
|
88
|
+
# pollute the namespace a little...
|
89
|
+
#
|
90
|
+
def fattrs(*a, &b)
|
91
|
+
__fattrs__(*a, &b)
|
92
|
+
end
|
93
|
+
alias_method "fattr", "fattrs"
|
94
|
+
|
95
|
+
def to_hash
|
96
|
+
__fattrs__.inject(Hash.new){|h,a| h.update(a => __send__(a))}
|
97
|
+
end
|
98
|
+
alias_method "to_h", "to_hash"
|
99
|
+
|
100
|
+
def respond_to?(*a, &b)
|
101
|
+
true
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
Openobject = OpenObject
|
106
|
+
|
107
|
+
class Object
|
108
|
+
def Open *a, &b
|
109
|
+
OpenObject.new(*a, &b)
|
110
|
+
end
|
111
|
+
|
112
|
+
def openobject(*a, &b)
|
113
|
+
OpenObject.new(*a, &b)
|
114
|
+
end
|
115
|
+
|
116
|
+
def oo *a, &b
|
117
|
+
OpenObject.new(*a, &b)
|
118
|
+
end
|
119
|
+
end
|
data/openobject.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
## openobject.gemspec
|
2
|
+
#
|
3
|
+
|
4
|
+
Gem::Specification::new do |spec|
|
5
|
+
spec.name = "openobject"
|
6
|
+
spec.version = "1.0.0"
|
7
|
+
spec.platform = Gem::Platform::RUBY
|
8
|
+
spec.summary = "openobject"
|
9
|
+
spec.description = "description: openobject kicks the ass"
|
10
|
+
|
11
|
+
spec.files = ["install.rb", "lib", "lib/openobject.rb", "openobject.gemspec", "Rakefile", "README", "README.erb", "sample", "sample/a.rb", "sample/b.rb", "sample/c.rb", "sample/d.rb", "sample/e.rb", "sample/f.rb"]
|
12
|
+
spec.executables = []
|
13
|
+
|
14
|
+
spec.require_path = "lib"
|
15
|
+
|
16
|
+
spec.has_rdoc = true
|
17
|
+
spec.test_files = nil
|
18
|
+
#spec.add_dependency 'lib', '>= version'
|
19
|
+
spec.add_dependency 'fattr'
|
20
|
+
|
21
|
+
spec.extensions.push(*[])
|
22
|
+
|
23
|
+
spec.rubyforge_project = "codeforpeople"
|
24
|
+
spec.author = "Ara T. Howard"
|
25
|
+
spec.email = "ara.t.howard@gmail.com"
|
26
|
+
spec.homepage = "http://github.com/ahoward/openobject/tree/master"
|
27
|
+
end
|
data/sample/a.rb
ADDED
data/sample/b.rb
ADDED
data/sample/c.rb
ADDED
data/sample/d.rb
ADDED
data/sample/e.rb
ADDED
data/sample/f.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'openobject'
|
2
|
+
|
3
|
+
# by default you cannot retrive unset values
|
4
|
+
#
|
5
|
+
o = oo
|
6
|
+
begin; o.foo; rescue NameError; p NameError; end
|
7
|
+
|
8
|
+
#=> NameError
|
9
|
+
|
10
|
+
# but you can set anything
|
11
|
+
#
|
12
|
+
o = oo
|
13
|
+
o.foo = 42
|
14
|
+
p o.foo
|
15
|
+
|
16
|
+
#=> 42
|
17
|
+
|
18
|
+
# blocks can extend openobjects
|
19
|
+
#
|
20
|
+
o = oo{ def bar() 42 end }
|
21
|
+
p o.bar
|
22
|
+
|
23
|
+
#=> 42
|
24
|
+
|
25
|
+
# you can set a default value which will be returned for anything
|
26
|
+
# missing value
|
27
|
+
#
|
28
|
+
o = oo{ default 42 }
|
29
|
+
p o.bar
|
30
|
+
|
31
|
+
#=> 42
|
32
|
+
|
33
|
+
# and the default value itself can be someting block/proc-like
|
34
|
+
#
|
35
|
+
n = 40
|
36
|
+
o = oo{ default{ n += 2 } }
|
37
|
+
p o.foo
|
38
|
+
|
39
|
+
#=> 42
|
metadata
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: openobject
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 1
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
version: 1.0.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Ara T. Howard
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-09-12 00:00:00 -06:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: fattr
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
type: :runtime
|
32
|
+
version_requirements: *id001
|
33
|
+
description: "description: openobject kicks the ass"
|
34
|
+
email: ara.t.howard@gmail.com
|
35
|
+
executables: []
|
36
|
+
|
37
|
+
extensions: []
|
38
|
+
|
39
|
+
extra_rdoc_files: []
|
40
|
+
|
41
|
+
files:
|
42
|
+
- install.rb
|
43
|
+
- lib/openobject.rb
|
44
|
+
- openobject.gemspec
|
45
|
+
- Rakefile
|
46
|
+
- README
|
47
|
+
- README.erb
|
48
|
+
- sample/a.rb
|
49
|
+
- sample/b.rb
|
50
|
+
- sample/c.rb
|
51
|
+
- sample/d.rb
|
52
|
+
- sample/e.rb
|
53
|
+
- sample/f.rb
|
54
|
+
has_rdoc: true
|
55
|
+
homepage: http://github.com/ahoward/openobject/tree/master
|
56
|
+
licenses: []
|
57
|
+
|
58
|
+
post_install_message:
|
59
|
+
rdoc_options: []
|
60
|
+
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
segments:
|
69
|
+
- 0
|
70
|
+
version: "0"
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
segments:
|
77
|
+
- 0
|
78
|
+
version: "0"
|
79
|
+
requirements: []
|
80
|
+
|
81
|
+
rubyforge_project: codeforpeople
|
82
|
+
rubygems_version: 1.3.7
|
83
|
+
signing_key:
|
84
|
+
specification_version: 3
|
85
|
+
summary: openobject
|
86
|
+
test_files: []
|
87
|
+
|