shared 0.4.2
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 +183 -0
- data/gemspec.rb +38 -0
- data/gen_readme.rb +35 -0
- data/install.rb +214 -0
- data/lib/shared.rb +59 -0
- data/samples/a.rb +20 -0
- data/samples/b.rb +18 -0
- data/samples/c.rb +25 -0
- data/samples/d.rb +21 -0
- data/samples/e.rb +30 -0
- metadata +73 -0
data/README
ADDED
@@ -0,0 +1,183 @@
|
|
1
|
+
NAME
|
2
|
+
shared.rb
|
3
|
+
|
4
|
+
DESCRIPTION
|
5
|
+
super simple super power sharing of instance and class level code
|
6
|
+
|
7
|
+
INSTALL
|
8
|
+
gem install shared
|
9
|
+
|
10
|
+
URIS
|
11
|
+
http://rubyforge.org/projects/codeforpeople
|
12
|
+
http://codeforpeople.com/lib/ruby/
|
13
|
+
|
14
|
+
HISTORY
|
15
|
+
0.4.2
|
16
|
+
initial version
|
17
|
+
|
18
|
+
SAMPLES
|
19
|
+
|
20
|
+
<========< samples/a.rb >========>
|
21
|
+
|
22
|
+
~ > cat samples/a.rb
|
23
|
+
|
24
|
+
# shared.rb is a very simple and very powerful method of sharing code between
|
25
|
+
# classes.
|
26
|
+
#
|
27
|
+
require 'shared'
|
28
|
+
|
29
|
+
shared(:code) do
|
30
|
+
def classname() self.class.name end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Foo
|
34
|
+
include shared(:code)
|
35
|
+
end
|
36
|
+
|
37
|
+
class Bar
|
38
|
+
include shared(:code)
|
39
|
+
end
|
40
|
+
|
41
|
+
p Foo.new.classname #=> "Foo"
|
42
|
+
|
43
|
+
p Bar.new.classname #=> "Bar"
|
44
|
+
|
45
|
+
~ > ruby samples/a.rb
|
46
|
+
|
47
|
+
"Foo"
|
48
|
+
"Bar"
|
49
|
+
|
50
|
+
|
51
|
+
<========< samples/b.rb >========>
|
52
|
+
|
53
|
+
~ > cat samples/b.rb
|
54
|
+
|
55
|
+
# shared.rb allows natural declaration of both instance and class-level
|
56
|
+
# methods - it's more than simple module inclusion
|
57
|
+
#
|
58
|
+
|
59
|
+
require 'shared'
|
60
|
+
|
61
|
+
shared('methods') do
|
62
|
+
def self.class_method() 40 end
|
63
|
+
|
64
|
+
def instance_method() 2 end
|
65
|
+
end
|
66
|
+
|
67
|
+
class C
|
68
|
+
include shared('methods')
|
69
|
+
end
|
70
|
+
|
71
|
+
p(C.class_method + C.new.instance_method) #=> 42
|
72
|
+
|
73
|
+
|
74
|
+
~ > ruby samples/b.rb
|
75
|
+
|
76
|
+
42
|
77
|
+
|
78
|
+
|
79
|
+
<========< samples/c.rb >========>
|
80
|
+
|
81
|
+
~ > cat samples/c.rb
|
82
|
+
|
83
|
+
# shared.rb works equally well with individual objects in addition to the
|
84
|
+
# normal class level usage
|
85
|
+
#
|
86
|
+
|
87
|
+
require 'shared'
|
88
|
+
|
89
|
+
shared(:meta_tools) do
|
90
|
+
def singleton_class &block
|
91
|
+
singleton_class =
|
92
|
+
class << self
|
93
|
+
self
|
94
|
+
end
|
95
|
+
block ? singleton_class.module_eval(&block) : singleton_class
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
a = %w( a b c )
|
100
|
+
|
101
|
+
a.extend shared(:meta_tools)
|
102
|
+
|
103
|
+
a.singleton_class do
|
104
|
+
def to_range() first .. last end
|
105
|
+
end
|
106
|
+
|
107
|
+
p a.to_range #=> "a".."c"
|
108
|
+
|
109
|
+
~ > ruby samples/c.rb
|
110
|
+
|
111
|
+
"a".."c"
|
112
|
+
|
113
|
+
|
114
|
+
<========< samples/d.rb >========>
|
115
|
+
|
116
|
+
~ > cat samples/d.rb
|
117
|
+
|
118
|
+
# an example use-case for shared.rb is sharing code bewteen classes that
|
119
|
+
# require both class level and instance level behaviour to be shared
|
120
|
+
#
|
121
|
+
|
122
|
+
require 'shared'
|
123
|
+
|
124
|
+
shared(:acts_as_named) do
|
125
|
+
validates_precence_of :name
|
126
|
+
|
127
|
+
def to_html() "<blink> #{ name } </blink>" end
|
128
|
+
end
|
129
|
+
|
130
|
+
class Model
|
131
|
+
def Model.validates_precence_of(*a) end
|
132
|
+
|
133
|
+
def name() 'zaphod' end
|
134
|
+
|
135
|
+
include shared(:acts_as_named)
|
136
|
+
end
|
137
|
+
|
138
|
+
p Model.new.to_html #=> "<blink> zaphod </blink>"
|
139
|
+
|
140
|
+
~ > ruby samples/d.rb
|
141
|
+
|
142
|
+
"<blink> zaphod </blink>"
|
143
|
+
|
144
|
+
|
145
|
+
<========< samples/e.rb >========>
|
146
|
+
|
147
|
+
~ > cat samples/e.rb
|
148
|
+
|
149
|
+
# it's important to note that the shared code is injected into the reciever
|
150
|
+
# fresh on each call and, in that way, the effect is rather macro like
|
151
|
+
#
|
152
|
+
|
153
|
+
require 'shared'
|
154
|
+
|
155
|
+
share(:instance_tracker) do
|
156
|
+
const_set :Instances, []
|
157
|
+
|
158
|
+
def self.instances() const_get :Instances end
|
159
|
+
|
160
|
+
def self.new *a, &b
|
161
|
+
obj = super
|
162
|
+
ensure
|
163
|
+
instances << obj
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
class Foo
|
168
|
+
include shared(:instance_tracker)
|
169
|
+
end
|
170
|
+
|
171
|
+
class Bar
|
172
|
+
include shared(:instance_tracker)
|
173
|
+
end
|
174
|
+
|
175
|
+
2.times{ Foo.new }
|
176
|
+
40.times{ Bar.new }
|
177
|
+
|
178
|
+
p(Foo.instances.size + Bar.instances.size)
|
179
|
+
|
180
|
+
~ > ruby samples/e.rb
|
181
|
+
|
182
|
+
42
|
183
|
+
|
data/gemspec.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
#! /usr/bin/env gem build
|
2
|
+
|
3
|
+
lib, version = File::basename(File::dirname(File::expand_path(__FILE__))).split %r/-/, 2
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
|
7
|
+
Gem::Specification::new do |spec|
|
8
|
+
$VERBOSE = nil
|
9
|
+
|
10
|
+
shiteless = lambda do |list|
|
11
|
+
list.delete_if do |file|
|
12
|
+
file =~ %r/\.svn/ or
|
13
|
+
file =~ %r/\.tmp/
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
spec.name = lib
|
18
|
+
spec.version = version
|
19
|
+
spec.platform = Gem::Platform::RUBY
|
20
|
+
spec.summary = lib
|
21
|
+
|
22
|
+
spec.files = shiteless[Dir::glob("**/**")]
|
23
|
+
spec.executables = shiteless[Dir::glob("bin/*")].map{|exe| File::basename exe}
|
24
|
+
|
25
|
+
spec.require_path = "lib"
|
26
|
+
|
27
|
+
spec.has_rdoc = File::exist? "doc"
|
28
|
+
spec.test_suite_file = "test/#{ lib }.rb" if File::directory? "test"
|
29
|
+
#spec.add_dependency 'lib', '>= version'
|
30
|
+
spec.add_dependency 'fattr'
|
31
|
+
|
32
|
+
spec.extensions << "extconf.rb" if File::exists? "extconf.rb"
|
33
|
+
|
34
|
+
spec.rubyforge_project = 'codeforpeople'
|
35
|
+
spec.author = "Ara T. Howard"
|
36
|
+
spec.email = "ara.t.howard@gmail.com"
|
37
|
+
spec.homepage = "http://codeforpeople.com/lib/ruby/#{ lib }/"
|
38
|
+
end
|
data/gen_readme.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
|
5
|
+
$VERBOSE=nil
|
6
|
+
|
7
|
+
def indent s, n = 2
|
8
|
+
ws = ' ' * n
|
9
|
+
s.gsub %r/^/, ws
|
10
|
+
end
|
11
|
+
|
12
|
+
template = IO::read 'README.tmpl'
|
13
|
+
|
14
|
+
samples = ''
|
15
|
+
prompt = '~ > '
|
16
|
+
|
17
|
+
Dir['sample*/*'].sort.each do |sample|
|
18
|
+
samples << "\n" << " <========< #{ sample } >========>" << "\n\n"
|
19
|
+
|
20
|
+
cmd = "cat #{ sample }"
|
21
|
+
samples << indent(prompt + cmd, 2) << "\n\n"
|
22
|
+
samples << indent(`#{ cmd }`, 4) << "\n"
|
23
|
+
|
24
|
+
cmd = "ruby #{ sample }"
|
25
|
+
samples << indent(prompt + cmd, 2) << "\n\n"
|
26
|
+
|
27
|
+
cmd = "ruby -e'STDOUT.sync=true; exec %(ruby -Ilib #{ sample })'"
|
28
|
+
#cmd = "ruby -Ilib #{ sample }"
|
29
|
+
samples << indent(`#{ cmd } 2>&1`, 4) << "\n"
|
30
|
+
end
|
31
|
+
|
32
|
+
#samples.gsub! %r/^/, ' '
|
33
|
+
|
34
|
+
readme = template.gsub %r/^\s*@samples\s*$/, samples
|
35
|
+
print readme
|
data/install.rb
ADDED
@@ -0,0 +1,214 @@
|
|
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 (/\.svn/ =~ File.dirname(f))
|
40
|
+
next if f =~ %r/\.lnk/
|
41
|
+
next if f =~ %r/\.svn/
|
42
|
+
next if f =~ %r/\.swp/
|
43
|
+
next if f =~ %r/\.svn/
|
44
|
+
path.push f
|
45
|
+
dir |= [File.dirname(f)]
|
46
|
+
end
|
47
|
+
for f in dir
|
48
|
+
next if f == "."
|
49
|
+
next if f == "CVS"
|
50
|
+
File::makedirs(File.join(destdir, f))
|
51
|
+
end
|
52
|
+
for f in path
|
53
|
+
next if (/\~$/ =~ f)
|
54
|
+
next if (/^\./ =~ File.basename(f))
|
55
|
+
unless bin
|
56
|
+
File::install(File.join(srcdir, f), File.join(destdir, f), mode, true)
|
57
|
+
else
|
58
|
+
from = File.join(srcdir, f)
|
59
|
+
to = File.join(destdir, f)
|
60
|
+
shebangify(from) do |sf|
|
61
|
+
$deferr.print from, " -> ", File::catname(from, to), "\n"
|
62
|
+
$deferr.printf "chmod %04o %s\n", mode, to
|
63
|
+
File::install(sf, to, mode, false)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
#}}}
|
68
|
+
end
|
69
|
+
def shebangify f
|
70
|
+
#{{{
|
71
|
+
open(f) do |fd|
|
72
|
+
buf = fd.read 42
|
73
|
+
if buf =~ %r/^\s*#\s*!.*ruby/o
|
74
|
+
ftmp = Tempfile::new("#{ $$ }_#{ File::basename(f) }")
|
75
|
+
begin
|
76
|
+
fd.rewind
|
77
|
+
ftmp.puts "#!#{ $ruby }"
|
78
|
+
while((buf = fd.read(8192)))
|
79
|
+
ftmp.write buf
|
80
|
+
end
|
81
|
+
ftmp.close
|
82
|
+
yield ftmp.path
|
83
|
+
ensure
|
84
|
+
ftmp.close!
|
85
|
+
end
|
86
|
+
else
|
87
|
+
yield f
|
88
|
+
end
|
89
|
+
end
|
90
|
+
#}}}
|
91
|
+
end
|
92
|
+
def ARGV.switch
|
93
|
+
#{{{
|
94
|
+
return nil if self.empty?
|
95
|
+
arg = self.shift
|
96
|
+
return nil if arg == '--'
|
97
|
+
if arg =~ /^-(.)(.*)/
|
98
|
+
return arg if $1 == '-'
|
99
|
+
raise 'unknown switch "-"' if $2.index('-')
|
100
|
+
self.unshift "-#{$2}" if $2.size > 0
|
101
|
+
"-#{$1}"
|
102
|
+
else
|
103
|
+
self.unshift arg
|
104
|
+
nil
|
105
|
+
end
|
106
|
+
#}}}
|
107
|
+
end
|
108
|
+
def ARGV.req_arg
|
109
|
+
#{{{
|
110
|
+
self.shift || raise('missing argument')
|
111
|
+
#}}}
|
112
|
+
end
|
113
|
+
def linkify d, linked = []
|
114
|
+
#--{{{
|
115
|
+
if test ?d, d
|
116
|
+
versioned = Dir[ File::join(d, "*-[0-9].[0-9].[0-9].rb") ]
|
117
|
+
versioned.each do |v|
|
118
|
+
src, dst = v, v.gsub(%r/\-[\d\.]+\.rb$/, '.rb')
|
119
|
+
lnk = nil
|
120
|
+
begin
|
121
|
+
if test ?l, dst
|
122
|
+
lnk = "#{ dst }.lnk"
|
123
|
+
puts "#{ dst } -> #{ lnk }"
|
124
|
+
File::rename dst, lnk
|
125
|
+
end
|
126
|
+
unless test ?e, dst
|
127
|
+
puts "#{ src } -> #{ dst }"
|
128
|
+
File::copy src, dst
|
129
|
+
linked << dst
|
130
|
+
end
|
131
|
+
ensure
|
132
|
+
if lnk
|
133
|
+
at_exit do
|
134
|
+
puts "#{ lnk } -> #{ dst }"
|
135
|
+
File::rename lnk, dst
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
linked
|
142
|
+
#--}}}
|
143
|
+
end
|
144
|
+
|
145
|
+
|
146
|
+
#
|
147
|
+
# main program
|
148
|
+
#
|
149
|
+
|
150
|
+
libdir = $site_libdir
|
151
|
+
bindir = $bindir
|
152
|
+
no_linkify = false
|
153
|
+
linked = nil
|
154
|
+
help = false
|
155
|
+
|
156
|
+
usage = <<-usage
|
157
|
+
#{ File::basename $0 }
|
158
|
+
-d, --destdir <destdir>
|
159
|
+
-l, --libdir <libdir>
|
160
|
+
-b, --bindir <bindir>
|
161
|
+
-r, --ruby <ruby>
|
162
|
+
-n, --no_linkify
|
163
|
+
-s, --sudo
|
164
|
+
-h, --help
|
165
|
+
usage
|
166
|
+
|
167
|
+
begin
|
168
|
+
while switch = ARGV.switch
|
169
|
+
case switch
|
170
|
+
when '-d', '--destdir'
|
171
|
+
libdir = ARGV.req_arg
|
172
|
+
when '-l', '--libdir'
|
173
|
+
libdir = ARGV.req_arg
|
174
|
+
when '-b', '--bindir'
|
175
|
+
bindir = ARGV.req_arg
|
176
|
+
when '-r', '--ruby'
|
177
|
+
$ruby = ARGV.req_arg
|
178
|
+
when '-n', '--no_linkify'
|
179
|
+
no_linkify = true
|
180
|
+
when '-s', '--sudo'
|
181
|
+
sudo = 'sudo'
|
182
|
+
when '-h', '--help'
|
183
|
+
help = true
|
184
|
+
else
|
185
|
+
raise "unknown switch #{switch.dump}"
|
186
|
+
end
|
187
|
+
end
|
188
|
+
rescue
|
189
|
+
STDERR.puts $!.to_s
|
190
|
+
STDERR.puts usage
|
191
|
+
exit 1
|
192
|
+
end
|
193
|
+
|
194
|
+
if help
|
195
|
+
STDOUT.puts usage
|
196
|
+
exit
|
197
|
+
end
|
198
|
+
|
199
|
+
system "#{ sudo } #{ $ruby } pre-install.rb" if test(?s, 'pre-install.rb')
|
200
|
+
|
201
|
+
unless no_linkify
|
202
|
+
linked = linkify('lib') + linkify('bin')
|
203
|
+
end
|
204
|
+
|
205
|
+
system "#{ $ruby } extconf.rb && make && #{ sudo } make install" if test(?s, 'extconf.rb')
|
206
|
+
|
207
|
+
install_rb(LIBDIR, libdir, LIBDIR_MODE)
|
208
|
+
install_rb(BINDIR, bindir, BINDIR_MODE, bin=true)
|
209
|
+
|
210
|
+
if linked
|
211
|
+
linked.each{|path| File::rm_f path}
|
212
|
+
end
|
213
|
+
|
214
|
+
system "#{ sudo } #{ $ruby } post-install.rb" if test(?s, 'post-install.rb')
|
data/lib/shared.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
module Shared
|
2
|
+
Code = {}
|
3
|
+
|
4
|
+
def shared name, &block
|
5
|
+
key = key_for name
|
6
|
+
|
7
|
+
return Code[key] if block.nil?
|
8
|
+
|
9
|
+
m = (Code[key] || Module.new)
|
10
|
+
|
11
|
+
singleton_class(m) do
|
12
|
+
unless defined?(@@blocks)
|
13
|
+
@@blocks = []
|
14
|
+
|
15
|
+
define_method(:blocks){ @@blocks }
|
16
|
+
|
17
|
+
define_method(:included) do |other|
|
18
|
+
blocks.each{|b| other.send(:module_eval, &b)}
|
19
|
+
end
|
20
|
+
|
21
|
+
define_method(:extend_object) do |other|
|
22
|
+
Shared.singleton_class(other) do
|
23
|
+
m.blocks.each{|b| module_eval &b}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
m.blocks << block
|
30
|
+
|
31
|
+
Code[key] ||= m
|
32
|
+
end
|
33
|
+
|
34
|
+
alias_method 'share', 'shared'
|
35
|
+
|
36
|
+
def key_for name
|
37
|
+
name.to_s.strip.downcase
|
38
|
+
end
|
39
|
+
|
40
|
+
def singleton_class object, &block
|
41
|
+
singleton_class =
|
42
|
+
class << object
|
43
|
+
self
|
44
|
+
end
|
45
|
+
block ? singleton_class.module_eval(&block) : singleton_class
|
46
|
+
end
|
47
|
+
|
48
|
+
extend self
|
49
|
+
end
|
50
|
+
|
51
|
+
class Object
|
52
|
+
def share *a, &b
|
53
|
+
Shared.share *a, &b
|
54
|
+
end
|
55
|
+
|
56
|
+
def shared *a, &b
|
57
|
+
Shared.shared *a, &b
|
58
|
+
end
|
59
|
+
end
|
data/samples/a.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# shared.rb is a very simple and very powerful method of sharing code between
|
2
|
+
# classes.
|
3
|
+
#
|
4
|
+
require 'shared'
|
5
|
+
|
6
|
+
shared(:code) do
|
7
|
+
def classname() self.class.name end
|
8
|
+
end
|
9
|
+
|
10
|
+
class Foo
|
11
|
+
include shared(:code)
|
12
|
+
end
|
13
|
+
|
14
|
+
class Bar
|
15
|
+
include shared(:code)
|
16
|
+
end
|
17
|
+
|
18
|
+
p Foo.new.classname #=> "Foo"
|
19
|
+
|
20
|
+
p Bar.new.classname #=> "Bar"
|
data/samples/b.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# shared.rb allows natural declaration of both instance and class-level
|
2
|
+
# methods - it's more than simple module inclusion
|
3
|
+
#
|
4
|
+
|
5
|
+
require 'shared'
|
6
|
+
|
7
|
+
shared('methods') do
|
8
|
+
def self.class_method() 40 end
|
9
|
+
|
10
|
+
def instance_method() 2 end
|
11
|
+
end
|
12
|
+
|
13
|
+
class C
|
14
|
+
include shared('methods')
|
15
|
+
end
|
16
|
+
|
17
|
+
p(C.class_method + C.new.instance_method) #=> 42
|
18
|
+
|
data/samples/c.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# shared.rb works equally well with individual objects in addition to the
|
2
|
+
# normal class level usage
|
3
|
+
#
|
4
|
+
|
5
|
+
require 'shared'
|
6
|
+
|
7
|
+
shared(:meta_tools) do
|
8
|
+
def singleton_class &block
|
9
|
+
singleton_class =
|
10
|
+
class << self
|
11
|
+
self
|
12
|
+
end
|
13
|
+
block ? singleton_class.module_eval(&block) : singleton_class
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
a = %w( a b c )
|
18
|
+
|
19
|
+
a.extend shared(:meta_tools)
|
20
|
+
|
21
|
+
a.singleton_class do
|
22
|
+
def to_range() first .. last end
|
23
|
+
end
|
24
|
+
|
25
|
+
p a.to_range #=> "a".."c"
|
data/samples/d.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# an example use-case for shared.rb is sharing code bewteen classes that
|
2
|
+
# require both class level and instance level behaviour to be shared
|
3
|
+
#
|
4
|
+
|
5
|
+
require 'shared'
|
6
|
+
|
7
|
+
shared(:acts_as_named) do
|
8
|
+
validates_precence_of :name
|
9
|
+
|
10
|
+
def to_html() "<blink> #{ name } </blink>" end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Model
|
14
|
+
def Model.validates_precence_of(*a) end
|
15
|
+
|
16
|
+
def name() 'zaphod' end
|
17
|
+
|
18
|
+
include shared(:acts_as_named)
|
19
|
+
end
|
20
|
+
|
21
|
+
p Model.new.to_html #=> "<blink> zaphod </blink>"
|
data/samples/e.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# it's important to note that the shared code is injected into the reciever
|
2
|
+
# fresh on each call and, in that way, the effect is rather macro like
|
3
|
+
#
|
4
|
+
|
5
|
+
require 'shared'
|
6
|
+
|
7
|
+
share(:instance_tracker) do
|
8
|
+
const_set :Instances, []
|
9
|
+
|
10
|
+
def self.instances() const_get :Instances end
|
11
|
+
|
12
|
+
def self.new *a, &b
|
13
|
+
obj = super
|
14
|
+
ensure
|
15
|
+
instances << obj
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class Foo
|
20
|
+
include shared(:instance_tracker)
|
21
|
+
end
|
22
|
+
|
23
|
+
class Bar
|
24
|
+
include shared(:instance_tracker)
|
25
|
+
end
|
26
|
+
|
27
|
+
2.times{ Foo.new }
|
28
|
+
40.times{ Bar.new }
|
29
|
+
|
30
|
+
p(Foo.instances.size + Bar.instances.size)
|
metadata
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: shared
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ara T. Howard
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-11-09 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: fattr
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
description:
|
26
|
+
email: ara.t.howard@gmail.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files: []
|
32
|
+
|
33
|
+
files:
|
34
|
+
- gemspec.rb
|
35
|
+
- gen_readme.rb
|
36
|
+
- install.rb
|
37
|
+
- lib
|
38
|
+
- lib/shared.rb
|
39
|
+
- README
|
40
|
+
- samples
|
41
|
+
- samples/a.rb
|
42
|
+
- samples/b.rb
|
43
|
+
- samples/c.rb
|
44
|
+
- samples/d.rb
|
45
|
+
- samples/e.rb
|
46
|
+
has_rdoc: false
|
47
|
+
homepage: http://codeforpeople.com/lib/ruby/shared/
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options: []
|
50
|
+
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
version:
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: "0"
|
64
|
+
version:
|
65
|
+
requirements: []
|
66
|
+
|
67
|
+
rubyforge_project: codeforpeople
|
68
|
+
rubygems_version: 1.2.0
|
69
|
+
signing_key:
|
70
|
+
specification_version: 2
|
71
|
+
summary: shared
|
72
|
+
test_files: []
|
73
|
+
|