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 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
+