spiceinit 0.0.1
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/.gitignore +4 -0
- data/LICENSE +20 -0
- data/README.rdoc +220 -0
- data/Rakefile +16 -0
- data/examples/inspice.rb +80 -0
- data/examples/modspice.rb +76 -0
- data/lib/spice_init.rb +1 -0
- data/lib/spiceinit/extend.rb +9 -0
- data/lib/spiceinit/extract_options.rb +36 -0
- data/lib/spiceinit/instance.rb +52 -0
- data/lib/spiceinit/module.rb +53 -0
- data/lib/spiceinit/version.rb +3 -0
- data/lib/spiceinit.rb +4 -0
- data/spec/insinit_spec.rb +58 -0
- data/spec/modinit_spec.rb +42 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/spiced/instance.rb +82 -0
- data/spec/spiced/module.rb +23 -0
- data/spiceinit.gemspec +27 -0
- metadata +108 -0
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Luciano Altube
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,220 @@
|
|
1
|
+
=SpiceInit
|
2
|
+
Sometimes I want a simple way of initializing an object or setting class/module methods from a hash.
|
3
|
+
|
4
|
+
==Instances
|
5
|
+
With <tt>SpiceInit</tt> to initialize an instance of some class you can use <tt>inspice</tt> instead of <tt>new</tt>
|
6
|
+
|
7
|
+
For example:
|
8
|
+
|
9
|
+
class Person;end
|
10
|
+
|
11
|
+
person = Person.inspice(:name => "Lucky", :last_name => "Luke", :is_cool? => true)
|
12
|
+
p person
|
13
|
+
# => #<Person:0xb93c @name="Lucky", @last_name="Luke", @is_cool=true>
|
14
|
+
p person.name
|
15
|
+
# => "Lucky"
|
16
|
+
p person.last_name
|
17
|
+
# => "Luke"
|
18
|
+
p person.is_cool?
|
19
|
+
# => true
|
20
|
+
|
21
|
+
If you want to track the spices added without going through <tt>methods</tt> you can pass <tt>true</tt> to the <tt>:track_spices</tt> option.
|
22
|
+
person = Person.inspice(:name => "Lucky", :last_name => "Luke",
|
23
|
+
:is_cool? => true, :track_spices => true)
|
24
|
+
p person.spices_added
|
25
|
+
# => ["is_cool?", "is_cool=", "last_name=", "name", "name=", "last_name"]
|
26
|
+
|
27
|
+
You can also have some atributtes defined already so if a block is given the new object will be in scope.
|
28
|
+
class Person
|
29
|
+
attr_accessor :smokes
|
30
|
+
end
|
31
|
+
|
32
|
+
person = Person.inspice(:name => "Lucky", :last_name => "Luke", :is_cool? => true) do |ll|
|
33
|
+
ll.smokes = 'cigarettes'
|
34
|
+
end
|
35
|
+
|
36
|
+
p person
|
37
|
+
# => #<Person:0x9eac @is_cool=true, @smokes="cigarettes", @name="Lucky", @last_name="Luke">
|
38
|
+
p person.smokes
|
39
|
+
# => "cigarettes"
|
40
|
+
person.smokes = 'cigars'
|
41
|
+
p person.smokes
|
42
|
+
# => "cigars"
|
43
|
+
|
44
|
+
You can also have an <tt>initialize</tt> method with required arguments. In that case, you should provide them before the hash.
|
45
|
+
class Person
|
46
|
+
attr_accessor :smokes, :kind
|
47
|
+
def initialize(kind)
|
48
|
+
@kind = kind
|
49
|
+
|
50
|
+
# this will not run if you passed a block to :inspace
|
51
|
+
if block_given?
|
52
|
+
yield(self)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
person = Person.inspice('comic',:name => "Lucky", :last_name => "Luke", :is_cool? => true) do |ll|
|
58
|
+
ll.smokes = 'cigarettes'
|
59
|
+
end
|
60
|
+
|
61
|
+
p person
|
62
|
+
# => <Person:0x9128 @kind="comic", @smokes="cigarettes", @name="Lucky", @last_name="Luke", @is_cool=true>
|
63
|
+
Note: <tt>initialize</tt> is called before the block (if given to <tt>inspice</tt>) so block variable assignments will override any other assignment you are doing at <tt>initialize</tt>.
|
64
|
+
class Person
|
65
|
+
attr_accessor :smokes, :kind
|
66
|
+
def initialize(kind=nil)
|
67
|
+
@kind = kind
|
68
|
+
@smokes = 'cigars'
|
69
|
+
# this will not run if you passed a block to :inspace
|
70
|
+
if block_given?
|
71
|
+
yield(self)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
person = Person.inspice('drama',:name => "Lucky", :last_name => "Luke", :is_cool? => true) do |ll|
|
77
|
+
ll.smokes = 'cigarettes'
|
78
|
+
ll.kind = 'comic'
|
79
|
+
end
|
80
|
+
|
81
|
+
p person
|
82
|
+
# => #<Person:0xb4dc @last_name="Luke", @name="Lucky", @is_cool=true, @smokes="cigarettes", @kind="comic">
|
83
|
+
|
84
|
+
person = Person.inspice('comic',:name => "Lucky", :last_name => "Luke", :is_cool? => true)
|
85
|
+
|
86
|
+
p person
|
87
|
+
# => #<Person:0xad5c @last_name="Luke", @name="Lucky", @is_cool=true, @smokes="cigars", @kind="comic">
|
88
|
+
|
89
|
+
Sure, you can still instantiate with <tt>new</tt>
|
90
|
+
person = Person.new('friendly') do |f|
|
91
|
+
f.smokes = false
|
92
|
+
end
|
93
|
+
|
94
|
+
p person.kind
|
95
|
+
# => "friendly"
|
96
|
+
p person.smokes
|
97
|
+
# => false
|
98
|
+
p person
|
99
|
+
# => #<Person:0x88e0 @smokes=false, @kind="friendly">
|
100
|
+
|
101
|
+
When you pass a <tt>proc</tt> as a value you must call the key method as a <tt>proc</tt> also.
|
102
|
+
person = Person.inspice('comic',:name => "Lucky", :last_name => "Luke",
|
103
|
+
:says => Proc.new {|obj,str| "#{obj.name} says #{str}"})
|
104
|
+
|
105
|
+
p person.says[person,'hi there'] # or person.says.call(person,'hi there')
|
106
|
+
# => "Lucky says hi there"
|
107
|
+
|
108
|
+
Another way of using <tt>inspice</tt> is with factory methods.
|
109
|
+
class Person
|
110
|
+
def self.new
|
111
|
+
inspice :name => 'Tintin'
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
person = Person.new
|
116
|
+
p person
|
117
|
+
# => #<Person:0xb374 @name="Tintin">
|
118
|
+
p person.name
|
119
|
+
# => "Tintin"
|
120
|
+
person.name = 'Lucky'
|
121
|
+
p person.name
|
122
|
+
# => "Lucky"
|
123
|
+
p person
|
124
|
+
# => #<Person:0xb374 @name="Lucky">
|
125
|
+
person = Person.new do |c|
|
126
|
+
person.name = 'Tintin'
|
127
|
+
end
|
128
|
+
p person
|
129
|
+
# => #<Person:0xb180 @name="Tintin">
|
130
|
+
p person.name
|
131
|
+
# => "Tintin"
|
132
|
+
person.name = 'Lucky'
|
133
|
+
p person
|
134
|
+
#<Person:0xb180 @name="Lucky">
|
135
|
+
p person.name
|
136
|
+
# => "Lucky"
|
137
|
+
|
138
|
+
==Modules and Classes
|
139
|
+
For Clasess and Modules you can use <tt>claspice</tt> or <tt>clasinit</tt> and <tt>modspice</tt> (they are method aliases for <tt>modinit</tt>) and
|
140
|
+
the usage is simillar to <tt>inspice</tt> but keyes are defined as class methods and values as class variables.
|
141
|
+
|
142
|
+
module LCD
|
143
|
+
modspice :core_image => "Hardware Accelerated", :main_display => true,
|
144
|
+
:mirror => "off", :online => true
|
145
|
+
|
146
|
+
class Display
|
147
|
+
claspice :resolution => "1440x960", :colors => "Millions", :brightness => 50,
|
148
|
+
:auto_adjust => true, :show_in_menu => true, :refresh_rate => "n/a"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
p LCD.core_image
|
153
|
+
# => "Hardware Accelerated"
|
154
|
+
p LCD.main_display
|
155
|
+
# => true
|
156
|
+
p LCD.mirror
|
157
|
+
# => "off"
|
158
|
+
p LCD.online
|
159
|
+
# => true
|
160
|
+
p LCD.class_variables
|
161
|
+
# => ["@@mirror", "@@online", "@@main_display", "@@core_image"]
|
162
|
+
p LCD::Display.resolution
|
163
|
+
# => "1440x960"
|
164
|
+
p LCD::Display.colors
|
165
|
+
# => "Millions"
|
166
|
+
p LCD::Display.brightness
|
167
|
+
# => 50
|
168
|
+
p LCD::Display.auto_adjust
|
169
|
+
# => true
|
170
|
+
p LCD::Display.show_in_menu
|
171
|
+
# => true
|
172
|
+
p LCD::Display.refresh_rate
|
173
|
+
# => "n/a"
|
174
|
+
p LCD::Display.class_variables
|
175
|
+
# => ["@@brightness", "@@refresh_rate", "@@show_in_menu", "@@colors", "@@auto_adjust", "@@resolution"]
|
176
|
+
|
177
|
+
module LCD
|
178
|
+
modspice :core_image => "Hardware Accelerated", :main_display => true,
|
179
|
+
:mirror => "off", :online => true, :track_spices => true
|
180
|
+
|
181
|
+
class Display
|
182
|
+
claspice :resolution => "1440x960", :colors => "Millions", :brightness => 50,
|
183
|
+
:auto_adjust => true, :show_in_menu => true, :refresh_rate => "n/a",
|
184
|
+
:track_spices => true
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
p LCD.spices_added
|
189
|
+
# => ["online=", "online", "core_image=", "core_image", "main_display=", "main_display", "mirror=", "mirror"]
|
190
|
+
p LCD::Display.spices_added
|
191
|
+
# => ["brightness=", "brightness", "auto_adjust=", "auto_adjust", "show_in_menu=", "show_in_menu",
|
192
|
+
# "refresh_rate=", "refresh_rate", "resolution=", "resolution", "colors=", "colors"]
|
193
|
+
|
194
|
+
# can also be inline
|
195
|
+
M = Module.new
|
196
|
+
M.modspice :core_image => "Hardware Accelerated", :main_display => true,
|
197
|
+
:mirror => "off", :online => true,
|
198
|
+
:track_spices => true
|
199
|
+
|
200
|
+
p M.spices_added
|
201
|
+
# => ["online=", "online", "core_image=", "core_image", "main_display=", "main_display", "mirror=", "mirror"]
|
202
|
+
p M.class_variables
|
203
|
+
# => ["@@main_display", "@@spices_added", "@@core_image", "@@mirror", "@@online"]
|
204
|
+
|
205
|
+
With clasess and modules key methods with <tt>proc</tt> values are defined with optional arguments making the method call more natural.
|
206
|
+
module Tiempo
|
207
|
+
FORMATS = {:short => "%m/%d/%y", :long => "%A, %B %d, %Y"}
|
208
|
+
modspice :fecha => Proc.new {|time,key| time.strftime(FORMATS[key.to_sym])},
|
209
|
+
:ahora => Proc.new {Time.now}
|
210
|
+
end
|
211
|
+
|
212
|
+
p Tiempo.fecha(Time.now,:short)
|
213
|
+
# => "11/14/10"
|
214
|
+
p Tiempo.fecha(Time.now,:long)
|
215
|
+
# => "Sunday, November 14, 2010"
|
216
|
+
p Tiempo.ahora
|
217
|
+
# => Sun Nov 14 02:56:19 -0200 2010
|
218
|
+
|
219
|
+
==License
|
220
|
+
Read LICENSE
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require File.expand_path("../lib/spiceinit/version", __FILE__)
|
3
|
+
|
4
|
+
require 'spec/rake/spectask'
|
5
|
+
Spec::Rake::SpecTask.new(:specs) do |t|
|
6
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
7
|
+
t.spec_opts = ["--colour","--format nested"]
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'rake/rdoctask'
|
11
|
+
Rake::RDocTask.new do |rdoc|
|
12
|
+
rdoc.rdoc_dir = 'rdoc'
|
13
|
+
rdoc.title = "SpiceInit #{SpiceInit::VERSION}"
|
14
|
+
rdoc.rdoc_files.include('README*')
|
15
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
16
|
+
end
|
data/examples/inspice.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'spice_init'
|
3
|
+
|
4
|
+
class Person;end
|
5
|
+
|
6
|
+
person = Person.inspice(:name => "Lucky", :last_name => "Luke", :is_cool? => true)
|
7
|
+
p person
|
8
|
+
# => #<Person:0xb93c @name="Lucky", @last_name="Luke", @is_cool=true>
|
9
|
+
p person.name
|
10
|
+
# => "Lucky"
|
11
|
+
p person.last_name
|
12
|
+
# => "Luke"
|
13
|
+
p person.is_cool?
|
14
|
+
# => true
|
15
|
+
|
16
|
+
person = Person.inspice(:name => "Lucky", :last_name => "Luke",
|
17
|
+
:is_cool? => true, :track_spices => true)
|
18
|
+
p person.spices_added
|
19
|
+
# => ["is_cool?", "is_cool=", "last_name=", "name", "name=", "last_name"]
|
20
|
+
|
21
|
+
class Person
|
22
|
+
attr_accessor :smokes
|
23
|
+
end
|
24
|
+
|
25
|
+
person = Person.inspice(:name => "Lucky", :last_name => "Luke", :is_cool? => true) do |ll|
|
26
|
+
ll.smokes = 'cigarettes'
|
27
|
+
end
|
28
|
+
|
29
|
+
p person
|
30
|
+
# => #<Person:0x9eac @is_cool=true, @smokes="cigarettes", @name="Lucky", @last_name="Luke">
|
31
|
+
p person.smokes
|
32
|
+
# => "cigarettes"
|
33
|
+
person.smokes = 'cigars'
|
34
|
+
p person.smokes
|
35
|
+
# => "cigars"
|
36
|
+
|
37
|
+
class Person
|
38
|
+
attr_accessor :smokes, :kind
|
39
|
+
def initialize(kind)
|
40
|
+
@kind = kind
|
41
|
+
if block_given?
|
42
|
+
yield(self)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
person = Person.inspice('comic',:name => "Lucky", :last_name => "Luke", :is_cool? => true) do |ll|
|
48
|
+
ll.smokes = 'cigarettes'
|
49
|
+
end
|
50
|
+
|
51
|
+
p person
|
52
|
+
# => <Person:0x9128 @kind="comic", @smokes="cigarettes", @name="Lucky", @last_name="Luke", @is_cool=true>
|
53
|
+
|
54
|
+
person = Person.inspice('drama',:name => "Lucky", :last_name => "Luke", :is_cool? => true) do |ll|
|
55
|
+
ll.smokes = 'cigarettes'
|
56
|
+
ll.kind = 'comic'
|
57
|
+
end
|
58
|
+
|
59
|
+
p person
|
60
|
+
# => #<Person:0xb4dc @last_name="Luke", @name="Lucky", @is_cool=true, @smokes="cigarettes", @kind="comic">
|
61
|
+
|
62
|
+
person = Person.inspice('comic',:name => "Lucky", :last_name => "Luke", :is_cool? => true)
|
63
|
+
|
64
|
+
p person
|
65
|
+
# => #<Person:0xad5c @last_name="Luke", @name="Lucky", @is_cool=true, @smokes="cigars", @kind="comic">
|
66
|
+
|
67
|
+
person = Person.new('friendly') do |f|
|
68
|
+
f.smokes = false
|
69
|
+
end
|
70
|
+
|
71
|
+
p person.kind
|
72
|
+
# => "friendly"
|
73
|
+
p person.smokes
|
74
|
+
# => false
|
75
|
+
p person
|
76
|
+
# => #<Person:0x88e0 @smokes=false, @kind="friendly">
|
77
|
+
|
78
|
+
person = Person.inspice('comic',:name => "Lucky", :last_name => "Luke", :says => Proc.new {|obj,str| "#{obj.name} says #{str}"})
|
79
|
+
p person.says[person,'hi there']
|
80
|
+
# => "Lucky says hi there"
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'spice_init'
|
3
|
+
|
4
|
+
module LCD
|
5
|
+
modspice :core_image => "Hardware Accelerated", :main_display => true,
|
6
|
+
:mirror => "off", :online => true
|
7
|
+
|
8
|
+
class Display
|
9
|
+
claspice :resolution => "1440x960", :colors => "Millions", :brightness => 50,
|
10
|
+
:auto_adjust => true, :show_in_menu => true, :refresh_rate => "n/a"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
p LCD.core_image
|
15
|
+
# => "Hardware Accelerated"
|
16
|
+
p LCD.main_display
|
17
|
+
# => true
|
18
|
+
p LCD.mirror
|
19
|
+
# => "off"
|
20
|
+
p LCD.online
|
21
|
+
# => true
|
22
|
+
p LCD.class_variables
|
23
|
+
# => ["@@mirror", "@@online", "@@main_display", "@@core_image"]
|
24
|
+
p LCD::Display.resolution
|
25
|
+
# => "1440x960"
|
26
|
+
p LCD::Display.colors
|
27
|
+
# => "Millions"
|
28
|
+
p LCD::Display.brightness
|
29
|
+
# => 50
|
30
|
+
p LCD::Display.auto_adjust
|
31
|
+
# => true
|
32
|
+
p LCD::Display.show_in_menu
|
33
|
+
# => true
|
34
|
+
p LCD::Display.refresh_rate
|
35
|
+
# => "n/a"
|
36
|
+
p LCD::Display.class_variables
|
37
|
+
# => ["@@brightness", "@@refresh_rate", "@@show_in_menu", "@@colors", "@@auto_adjust", "@@resolution"]
|
38
|
+
|
39
|
+
module LCD
|
40
|
+
modspice :core_image => "Hardware Accelerated", :main_display => true,
|
41
|
+
:mirror => "off", :online => true, :track_spices => true
|
42
|
+
|
43
|
+
class Display
|
44
|
+
claspice :resolution => "1440x960", :colors => "Millions", :brightness => 50,
|
45
|
+
:auto_adjust => true, :show_in_menu => true, :refresh_rate => "n/a",
|
46
|
+
:track_spices => true
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
p LCD.spices_added
|
51
|
+
# => ["online=", "online", "core_image=", "core_image", "main_display=", "main_display", "mirror=", "mirror"]
|
52
|
+
p LCD::Display.spices_added
|
53
|
+
# => ["brightness=", "brightness", "auto_adjust=", "auto_adjust", "show_in_menu=", "show_in_menu",
|
54
|
+
# "refresh_rate=", "refresh_rate", "resolution=", "resolution", "colors=", "colors"]
|
55
|
+
|
56
|
+
M = Module.new
|
57
|
+
M.modspice :core_image => "Hardware Accelerated", :main_display => true,
|
58
|
+
:mirror => "off", :online => true,
|
59
|
+
:track_spices => true
|
60
|
+
p M.spices_added
|
61
|
+
# => ["online=", "online", "core_image=", "core_image", "main_display=", "main_display", "mirror=", "mirror"]
|
62
|
+
p M.class_variables
|
63
|
+
# => ["@@main_display", "@@spices_added", "@@core_image", "@@mirror", "@@online"]
|
64
|
+
|
65
|
+
module Tiempo
|
66
|
+
FORMATS = {:short => "%m/%d/%y", :long => "%A, %B %d, %Y"}
|
67
|
+
modspice :fecha => Proc.new {|time,key| time.strftime(FORMATS[key.to_sym])},
|
68
|
+
:ahora => Proc.new {Time.now}
|
69
|
+
end
|
70
|
+
|
71
|
+
p Tiempo.fecha(Time.now,:short)
|
72
|
+
# => "11/14/10"
|
73
|
+
p Tiempo.fecha(Time.now,:long)
|
74
|
+
# => "Sunday, November 14, 2010"
|
75
|
+
p Tiempo.ahora
|
76
|
+
# => Sun Nov 14 02:56:19 -0200 2010
|
data/lib/spice_init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "spiceinit"
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Do nothing if ActiveSupport is present.
|
2
|
+
unless defined?(ActiveSupport)
|
3
|
+
|
4
|
+
# ActiveSupport is not loaded.
|
5
|
+
# However, we still need <tt>extract_options!</tt>
|
6
|
+
#
|
7
|
+
class Hash
|
8
|
+
# By default, only instances of Hash itself are extractable.
|
9
|
+
# Subclasses of Hash may implement this method and return
|
10
|
+
# true to declare themselves as extractable. If a Hash
|
11
|
+
# is extractable, Array#extract_options! pops it from
|
12
|
+
# the Array when it is the last element of the Array.
|
13
|
+
def extractable_options?
|
14
|
+
instance_of?(Hash)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class Array
|
19
|
+
# Extracts options from a set of arguments. Removes and returns the last
|
20
|
+
# element in the array if it's a hash, otherwise returns a blank hash.
|
21
|
+
#
|
22
|
+
# def options(*args)
|
23
|
+
# args.extract_options!
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# options(1, 2) # => {}
|
27
|
+
# options(1, 2, :a => :b) # => {:a=>:b}
|
28
|
+
def extract_options!
|
29
|
+
if last.is_a?(Hash) && last.extractable_options?
|
30
|
+
pop
|
31
|
+
else
|
32
|
+
{}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module SpiceInit
|
2
|
+
module Instance
|
3
|
+
def insinit(*args,&block)
|
4
|
+
|
5
|
+
object, options = allocate, args.extract_options!
|
6
|
+
track_spices = options.has_key?(:track_spices) ? options.delete(:track_spices) : false
|
7
|
+
|
8
|
+
# create an anonymous Module with features from options
|
9
|
+
features = ::Module.new do
|
10
|
+
options.each do |key,value|
|
11
|
+
match = key.to_s.match(/([\!\?]$)/)
|
12
|
+
if match
|
13
|
+
|
14
|
+
setter = var = match.pre_match
|
15
|
+
getter = setter + match[1]
|
16
|
+
|
17
|
+
define_method("#{getter}") do
|
18
|
+
instance_variable_get("@#{var}")
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_writer setter
|
22
|
+
object.instance_variable_set("@#{var}", value)
|
23
|
+
|
24
|
+
else
|
25
|
+
|
26
|
+
attr_accessor key
|
27
|
+
object.instance_variable_set("@#{key}", value)
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
define_method("spices_added") do
|
32
|
+
features.instance_methods.reject { |f| f =~ /spices_added/ }
|
33
|
+
end if track_spices
|
34
|
+
end
|
35
|
+
|
36
|
+
# extend object with features
|
37
|
+
object.extend(features)
|
38
|
+
|
39
|
+
# if there are some args make a call to initialize
|
40
|
+
# block is set to nil to avoid calling it twice on initialize
|
41
|
+
object.send(:initialize, *args, &block=nil)
|
42
|
+
|
43
|
+
# if a block is given then pass the object for more processing
|
44
|
+
yield(object) if block_given?
|
45
|
+
|
46
|
+
# return the final object
|
47
|
+
object
|
48
|
+
end
|
49
|
+
|
50
|
+
alias_method :inspice, :insinit
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module SpiceInit
|
2
|
+
module Module
|
3
|
+
def modinit(attributes={})
|
4
|
+
raise TypeError unless self.is_a?(Module)
|
5
|
+
|
6
|
+
track_spices = attributes.has_key?(:track_spices) ? attributes.delete(:track_spices) : false
|
7
|
+
|
8
|
+
if track_spices
|
9
|
+
class_variable_set("@@spices_added",[])
|
10
|
+
end
|
11
|
+
|
12
|
+
attributes.each do |key,value|
|
13
|
+
|
14
|
+
match = key.to_s.match(/([\!\?]$)/)
|
15
|
+
if match
|
16
|
+
setter = var = match.pre_match
|
17
|
+
getter = setter + match[1]
|
18
|
+
else
|
19
|
+
setter = getter = var = key
|
20
|
+
end
|
21
|
+
class_variable_set("@@#{var}",value)
|
22
|
+
module_eval %Q{
|
23
|
+
|
24
|
+
def self.#{getter}(*args)
|
25
|
+
if @@#{var}.is_a?(Proc)
|
26
|
+
@@#{var}.call(*args)
|
27
|
+
else
|
28
|
+
@@#{var}
|
29
|
+
end
|
30
|
+
rescue
|
31
|
+
raise ArgumentError
|
32
|
+
caller
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.#{setter}=(value)
|
36
|
+
@@#{var} = value
|
37
|
+
end
|
38
|
+
}
|
39
|
+
if track_spices
|
40
|
+
module_eval %Q{
|
41
|
+
def self.spices_added
|
42
|
+
@@spices_added
|
43
|
+
end
|
44
|
+
} unless respond_to?(:spices_added)
|
45
|
+
spices_added << "#{setter}=" << "#{getter}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
alias_method :clasinit, :modinit
|
50
|
+
alias_method :modspice, :modinit
|
51
|
+
alias_method :claspice, :modinit
|
52
|
+
end
|
53
|
+
end
|
data/lib/spiceinit.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
include Spiced::Instance
|
3
|
+
|
4
|
+
describe SpiceInit::Instance do
|
5
|
+
context "#insinit" do
|
6
|
+
it "defines inspice instance variables respecting the ones at initialize" do
|
7
|
+
person = Person.inspice(:name => "Lucky", :last_name => "Luke")
|
8
|
+
person.instance_variables.should include("@kind","@last_name","@name")
|
9
|
+
end
|
10
|
+
it "defines attribute readers" do
|
11
|
+
person = Person.inspice(:name => "Lucky", :last_name => "Luke")
|
12
|
+
[person.name,person.last_name].should include('Lucky','Luke')
|
13
|
+
end
|
14
|
+
it "defines attribute writers" do
|
15
|
+
person = Person.inspice(:name => "Lucky", :last_name => "Luke")
|
16
|
+
person.name = "Rey"
|
17
|
+
person.last_name = "Tintin"
|
18
|
+
[person.name,person.last_name].should include("Rey","Tintin")
|
19
|
+
end
|
20
|
+
it "defines accessors for keys ending with (! or ?)" do
|
21
|
+
person = Person.inspice(:cool? => true, :friendly? => true)
|
22
|
+
[person.cool?,person.friendly?].should include(true,true)
|
23
|
+
person.cool = false
|
24
|
+
person.friendly = false
|
25
|
+
[person.cool?,person.friendly?].should include(false,false)
|
26
|
+
end
|
27
|
+
it "can take a block which prevents any block at initialize from running" do
|
28
|
+
person = Person.inspice(:cool? => true, :friendly? => true) do |p|
|
29
|
+
p.smokes = false
|
30
|
+
p.kind = 'healthy'
|
31
|
+
end
|
32
|
+
[person.smokes,person.kind].should include(false,'healthy')
|
33
|
+
end
|
34
|
+
it "can set initialize arguments that could be expected at initialize" do
|
35
|
+
person = Person.inspice('friend')
|
36
|
+
person.kind.should be_eql('friend')
|
37
|
+
end
|
38
|
+
it "can set any attribute declared inside the class through the block" do
|
39
|
+
person = Person.inspice() do |p|
|
40
|
+
p.kind = 'comic'
|
41
|
+
p.smokes = false
|
42
|
+
end
|
43
|
+
[person.kind,person.smokes].should include(false,'comic')
|
44
|
+
end
|
45
|
+
it "can take a proc as a key value" do
|
46
|
+
person = Person.inspice(:says => Proc.new {|s| s})
|
47
|
+
person.says['hi!'].should be_eql('hi!')
|
48
|
+
end
|
49
|
+
it "can track spices added by passing :track_spices => true" do
|
50
|
+
person = Person.inspice(:track_spices => true, :cool? => true, :friendly? => true)
|
51
|
+
person.spices_added.should include("friendly?", "friendly=", "cool?", "cool=")
|
52
|
+
end
|
53
|
+
it "modules cannot use inspice" do
|
54
|
+
m = Module.new
|
55
|
+
lambda {m.inspice(:foo => 'bar')}.should raise_exception(NoMethodError)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
include Spiced::Module
|
3
|
+
|
4
|
+
describe SpiceInit::Module do
|
5
|
+
before(:each) do
|
6
|
+
@LCD = ::Module.new
|
7
|
+
@Tiempo = ::Module.new
|
8
|
+
end
|
9
|
+
context "#modinit" do
|
10
|
+
it "defines class variables for each key" do
|
11
|
+
@LCD.modspice LCD1
|
12
|
+
@LCD.class_variables.should include(*LCD1_CVARS)
|
13
|
+
end
|
14
|
+
it "defines class attribute readers" do
|
15
|
+
@LCD.modspice LCD1
|
16
|
+
LCD1.each do |k,v|
|
17
|
+
@LCD.send(k).should be_eql(v)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
it "defines class attribute writers" do
|
21
|
+
@LCD.modspice LCD1
|
22
|
+
writers = LCD1.keys.map {|k|(k.to_s.gsub(/\?/,'') << '=').to_sym}
|
23
|
+
writers.each {|w| @LCD.send w,'changed'}
|
24
|
+
LCD1.keys.each do |k|
|
25
|
+
@LCD.send(k).should be_eql('changed')
|
26
|
+
end
|
27
|
+
end
|
28
|
+
it "can track spices added by passing :track_spices => true" do
|
29
|
+
@LCD.modspice LCD2
|
30
|
+
@LCD.spices_added.should include(*LCD2_SPICES)
|
31
|
+
end
|
32
|
+
it "key methods with proc values are called as methods" do
|
33
|
+
@Tiempo.modspice TSPICES
|
34
|
+
@Tiempo.ahora.should be_kind_of(Time)
|
35
|
+
end
|
36
|
+
it "key methods with proc values can take expected arguments" do
|
37
|
+
now = Time.now
|
38
|
+
@Tiempo.modspice TSPICES
|
39
|
+
@Tiempo.fecha(now,:short).should be_eql(now.strftime(FORMATS[:short]))
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'spec'
|
3
|
+
|
4
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
5
|
+
# $LOAD_PATH.unshift(File.dirname(__FILE__))
|
6
|
+
|
7
|
+
require 'spiceinit'
|
8
|
+
|
9
|
+
module Spiced
|
10
|
+
autoload :Module, 'spiced/module'
|
11
|
+
autoload :Instance, 'spiced/instance'
|
12
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module Spiced
|
2
|
+
module Instance
|
3
|
+
class Person
|
4
|
+
attr_accessor :smokes, :kind
|
5
|
+
def initialize(kind=nil)
|
6
|
+
@kind = kind
|
7
|
+
if block_given?
|
8
|
+
yield(self)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
#
|
13
|
+
# person = Person.inspice('comic',:name => "Lucky", :last_name => "Luke", :is_cool? => true) do |ll|
|
14
|
+
# ll.smokes = 'cigarettes'
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# p person
|
18
|
+
# => <Person:0x9128 @kind="comic", @smokes="cigarettes", @name="Lucky", @last_name="Luke", @is_cool=true>
|
19
|
+
#
|
20
|
+
# person = Person.inspice('drama',:name => "Lucky", :last_name => "Luke", :is_cool? => true) do |ll|
|
21
|
+
# ll.smokes = 'cigarettes'
|
22
|
+
# ll.kind = 'comic'
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# p person
|
26
|
+
# => #<Person:0xb4dc @last_name="Luke", @name="Lucky", @is_cool=true, @smokes="cigarettes", @kind="comic">
|
27
|
+
#
|
28
|
+
# person = Person.inspice('comic',:name => "Lucky", :last_name => "Luke", :is_cool? => true)
|
29
|
+
#
|
30
|
+
# p person
|
31
|
+
# => #<Person:0xad5c @last_name="Luke", @name="Lucky", @is_cool=true, @smokes="cigars", @kind="comic">
|
32
|
+
#
|
33
|
+
# person = Person.new('friendly') do |f|
|
34
|
+
# f.smokes = false
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# p person.kind
|
38
|
+
# => "friendly"
|
39
|
+
# p person.smokes
|
40
|
+
# => false
|
41
|
+
# p person
|
42
|
+
# => #<Person:0x88e0 @smokes=false, @kind="friendly">
|
43
|
+
#
|
44
|
+
# person = Person.inspice('comic',:name => "Lucky", :last_name => "Luke", :says => Proc.new {|obj,str| "#{obj.name} says #{str}"})
|
45
|
+
# p person.says[person,'hi there']
|
46
|
+
# => "Lucky says hi there"
|
47
|
+
#
|
48
|
+
# class Person;end
|
49
|
+
#
|
50
|
+
# person = Person.inspice(:name => "Lucky", :last_name => "Luke", :is_cool? => true)
|
51
|
+
# p person
|
52
|
+
# => #<Person:0xb93c @name="Lucky", @last_name="Luke", @is_cool=true>
|
53
|
+
# p person.name
|
54
|
+
# => "Lucky"
|
55
|
+
# p person.last_name
|
56
|
+
# => "Luke"
|
57
|
+
# p person.is_cool?
|
58
|
+
# => true
|
59
|
+
#
|
60
|
+
# person = Person.inspice(:name => "Lucky", :last_name => "Luke",
|
61
|
+
# :is_cool? => true, :track_spices => true)
|
62
|
+
# p person.spices_added
|
63
|
+
# => ["is_cool?", "is_cool=", "last_name=", "name", "name=", "last_name"]
|
64
|
+
#
|
65
|
+
# class Person
|
66
|
+
# attr_accessor :smokes
|
67
|
+
# end
|
68
|
+
#
|
69
|
+
# person = Person.inspice(:name => "Lucky", :last_name => "Luke", :is_cool? => true) do |ll|
|
70
|
+
# ll.smokes = 'cigarettes'
|
71
|
+
# end
|
72
|
+
#
|
73
|
+
# p person
|
74
|
+
# => #<Person:0x9eac @is_cool=true, @smokes="cigarettes", @name="Lucky", @last_name="Luke">
|
75
|
+
# p person.smokes
|
76
|
+
# => "cigarettes"
|
77
|
+
# person.smokes = 'cigars'
|
78
|
+
# p person.smokes
|
79
|
+
# => "cigars"
|
80
|
+
#
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Spiced
|
2
|
+
module Module
|
3
|
+
LCD1 = {:core_image => "Hardware Accelerated", :main_display? => true,
|
4
|
+
:mirror => "off", :online => true}
|
5
|
+
LCD1_CVARS = LCD1.keys.map {|k| "@@#{k}".gsub(/\?$/,'')}
|
6
|
+
|
7
|
+
LCD2 = LCD1.merge(:track_spices => true)
|
8
|
+
LCD2_CVARS = LCD2.keys.map {|k| "@@#{k}"}
|
9
|
+
LCD2_SPICES = LCD1.keys.map {|k| k.to_s} + LCD1.keys.map {|k|(k.to_s.gsub(/\?/,'') << '=')}
|
10
|
+
|
11
|
+
# DISPLAY1 = {:resolution => "1440x960", :colors => "Millions", :brightness => 50,
|
12
|
+
# :auto_adjust => true, :show_in_menu => true, :refresh_rate => "n/a"}
|
13
|
+
# DISPLAY1_CVARS = DISPLAY1.keys.map {|k| "@@#{k}"}
|
14
|
+
#
|
15
|
+
# DISPLAY2 = DISPLAY1.merge(:track_spices => true)
|
16
|
+
# DISPLAY2_CVARS = DISPLAY2.keys.map {|k| "@@#{k}"}
|
17
|
+
|
18
|
+
FORMATS = {:short => "%m/%d/%y", :long => "%A, %B %d, %Y"}
|
19
|
+
|
20
|
+
TSPICES = {:fecha => Proc.new {|time,key| time.strftime(FORMATS[key.to_sym])},
|
21
|
+
:ahora => Proc.new {Time.now}}
|
22
|
+
end
|
23
|
+
end
|
data/spiceinit.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path("../lib/spiceinit/version", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "spiceinit"
|
6
|
+
s.version = SpiceInit::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = ['Luciano Altube']
|
9
|
+
s.email = ['55elements@gmail.com']
|
10
|
+
s.homepage = "https://github.com/djtek/spiceinit"
|
11
|
+
s.summary = "With spiceinit you can initialize with extra methods and/or add class methods from a hash."
|
12
|
+
s.description = "spiceinit - add spices to your rubies"
|
13
|
+
|
14
|
+
s.required_rubygems_version = ">= 1.3.6"
|
15
|
+
# s.rubyforge_project = "spiceinit"
|
16
|
+
|
17
|
+
s.add_development_dependency "rspec", "~> 1.3"
|
18
|
+
|
19
|
+
s.files = `git ls-files`.split("\n")
|
20
|
+
s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
|
21
|
+
s.require_path = 'lib'
|
22
|
+
|
23
|
+
s.extra_rdoc_files = ["LICENSE", "README.rdoc"]
|
24
|
+
s.rdoc_options = ['--title', 'spiceinit: add spices to your rubies',
|
25
|
+
'--main', 'README.rdoc', '--line-numbers', '--inline-source']
|
26
|
+
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: spiceinit
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Luciano Altube
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-11-15 00:00:00 -02:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rspec
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 9
|
30
|
+
segments:
|
31
|
+
- 1
|
32
|
+
- 3
|
33
|
+
version: "1.3"
|
34
|
+
type: :development
|
35
|
+
version_requirements: *id001
|
36
|
+
description: spiceinit - add spices to your rubies
|
37
|
+
email:
|
38
|
+
- 55elements@gmail.com
|
39
|
+
executables: []
|
40
|
+
|
41
|
+
extensions: []
|
42
|
+
|
43
|
+
extra_rdoc_files:
|
44
|
+
- LICENSE
|
45
|
+
- README.rdoc
|
46
|
+
files:
|
47
|
+
- .gitignore
|
48
|
+
- LICENSE
|
49
|
+
- README.rdoc
|
50
|
+
- Rakefile
|
51
|
+
- examples/inspice.rb
|
52
|
+
- examples/modspice.rb
|
53
|
+
- lib/spice_init.rb
|
54
|
+
- lib/spiceinit.rb
|
55
|
+
- lib/spiceinit/extend.rb
|
56
|
+
- lib/spiceinit/extract_options.rb
|
57
|
+
- lib/spiceinit/instance.rb
|
58
|
+
- lib/spiceinit/module.rb
|
59
|
+
- lib/spiceinit/version.rb
|
60
|
+
- spec/insinit_spec.rb
|
61
|
+
- spec/modinit_spec.rb
|
62
|
+
- spec/spec_helper.rb
|
63
|
+
- spec/spiced/instance.rb
|
64
|
+
- spec/spiced/module.rb
|
65
|
+
- spiceinit.gemspec
|
66
|
+
has_rdoc: true
|
67
|
+
homepage: https://github.com/djtek/spiceinit
|
68
|
+
licenses: []
|
69
|
+
|
70
|
+
post_install_message:
|
71
|
+
rdoc_options:
|
72
|
+
- --title
|
73
|
+
- "spiceinit: add spices to your rubies"
|
74
|
+
- --main
|
75
|
+
- README.rdoc
|
76
|
+
- --line-numbers
|
77
|
+
- --inline-source
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
hash: 3
|
86
|
+
segments:
|
87
|
+
- 0
|
88
|
+
version: "0"
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
hash: 23
|
95
|
+
segments:
|
96
|
+
- 1
|
97
|
+
- 3
|
98
|
+
- 6
|
99
|
+
version: 1.3.6
|
100
|
+
requirements: []
|
101
|
+
|
102
|
+
rubyforge_project:
|
103
|
+
rubygems_version: 1.3.7
|
104
|
+
signing_key:
|
105
|
+
specification_version: 3
|
106
|
+
summary: With spiceinit you can initialize with extra methods and/or add class methods from a hash.
|
107
|
+
test_files: []
|
108
|
+
|