spiceinit 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
4
+ Gemfile.lock
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
@@ -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,9 @@
1
+ Module.send :include, SpiceInit::Module
2
+ Class.send :include, SpiceInit::Instance
3
+ #
4
+ # class Module
5
+ # include SpiceInit::Module
6
+ # end
7
+ # class Class
8
+ # include SpiceInit::Instance
9
+ # end
@@ -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
@@ -0,0 +1,3 @@
1
+ module SpiceInit
2
+ VERSION = "0.0.1"
3
+ end
data/lib/spiceinit.rb ADDED
@@ -0,0 +1,4 @@
1
+ require "spiceinit/extract_options"
2
+ require "spiceinit/module"
3
+ require "spiceinit/instance"
4
+ require "spiceinit/extend"
@@ -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
@@ -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
+