named_arguments 0.0.4
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/History.txt +5 -0
- data/Manifest.txt +10 -0
- data/README.txt +48 -0
- data/Rakefile +17 -0
- data/lib/named_arguments.rb +258 -0
- data/lib/named_arguments/class_settings_mixin.rb +122 -0
- data/lib/named_arguments/hash_extended_tools.rb +94 -0
- data/lib/named_arguments/method_extensions.rb +51 -0
- data/test/test_helper.rb +2 -0
- data/test/unit/named_arguments_test.rb +59 -0
- metadata +66 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
History.txt
|
2
|
+
Manifest.txt
|
3
|
+
README.txt
|
4
|
+
Rakefile
|
5
|
+
lib/named_arguments.rb
|
6
|
+
lib/named_arguments/class_settings_mixin.rb
|
7
|
+
lib/named_arguments/hash_extended_tools.rb
|
8
|
+
lib/named_arguments/method_extensions.rb
|
9
|
+
test/unit/named_arguments_test.rb
|
10
|
+
test/test_helper.rb
|
data/README.txt
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
namedarguments
|
2
|
+
by FIX (your name)
|
3
|
+
FIX (url)
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
FIX (describe your package)
|
8
|
+
|
9
|
+
== FEATURES/PROBLEMS:
|
10
|
+
|
11
|
+
* FIX (list of features or problems)
|
12
|
+
|
13
|
+
== SYNOPSIS:
|
14
|
+
|
15
|
+
FIX (code sample of usage)
|
16
|
+
|
17
|
+
== REQUIREMENTS:
|
18
|
+
|
19
|
+
* FIX (list of requirements)
|
20
|
+
|
21
|
+
== INSTALL:
|
22
|
+
|
23
|
+
* FIX (sudo gem install, anything else)
|
24
|
+
|
25
|
+
== LICENSE:
|
26
|
+
|
27
|
+
(The MIT License)
|
28
|
+
|
29
|
+
Copyright (c) 2007 FIX
|
30
|
+
|
31
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
32
|
+
a copy of this software and associated documentation files (the
|
33
|
+
'Software'), to deal in the Software without restriction, including
|
34
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
35
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
36
|
+
permit persons to whom the Software is furnished to do so, subject to
|
37
|
+
the following conditions:
|
38
|
+
|
39
|
+
The above copyright notice and this permission notice shall be
|
40
|
+
included in all copies or substantial portions of the Software.
|
41
|
+
|
42
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
43
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
44
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
45
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
46
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
47
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
48
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'hoe'
|
5
|
+
require './lib/named_arguments.rb'
|
6
|
+
|
7
|
+
Hoe.new('named_arguments', NamedArguments::VERSION) do |p|
|
8
|
+
p.rubyforge_name = 'named_arguments'
|
9
|
+
# p.author = 'FIX'
|
10
|
+
# p.email = 'FIX'
|
11
|
+
# p.summary = 'FIX'
|
12
|
+
# p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
|
13
|
+
# p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
|
14
|
+
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
15
|
+
end
|
16
|
+
|
17
|
+
# vim: syntax=Ruby
|
@@ -0,0 +1,258 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/named_arguments/method_extensions'
|
2
|
+
require File.dirname(__FILE__) + '/named_arguments/hash_extended_tools'
|
3
|
+
require File.dirname(__FILE__) + '/named_arguments/class_settings_mixin'
|
4
|
+
|
5
|
+
# Adds the following features to a class:
|
6
|
+
#
|
7
|
+
# * Pass a hash to new and matching attributes
|
8
|
+
# will be set.
|
9
|
+
# * Set default values for arguments (attribute_defaults)
|
10
|
+
# * Require arguments (required_fields)
|
11
|
+
# * Require kind_of? tests for arguments (required_kind_of)
|
12
|
+
# * Change the type of the object passed in (type_converter)
|
13
|
+
#
|
14
|
+
# =Sample
|
15
|
+
#
|
16
|
+
# class Snark
|
17
|
+
# include NamedArguments
|
18
|
+
#
|
19
|
+
# attr_accessor :color, :size, :name
|
20
|
+
#
|
21
|
+
# attribute_defaults :color => 'blue', :size => lambda {|s| some_method_call(s)}
|
22
|
+
# required_fields :color, :name
|
23
|
+
# required_respond_to :name => :to_s
|
24
|
+
# required_kind_of? :size => Fixnum
|
25
|
+
# type_converter :size => Fixnum
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# = See also
|
29
|
+
#
|
30
|
+
# See ClassMethods for more methods:
|
31
|
+
#
|
32
|
+
# * ClassMethods#type_converter
|
33
|
+
# * ClassMethods#option_attr
|
34
|
+
module NamedArguments
|
35
|
+
VERSION = '0.0.4'
|
36
|
+
|
37
|
+
def self.included target # :nodoc:
|
38
|
+
target.class_eval do
|
39
|
+
include HashExtendedTools
|
40
|
+
include ClassSettingsMixin
|
41
|
+
extend ClassMethods
|
42
|
+
create_class_settings_method :required_fields
|
43
|
+
create_class_settings_method :required_kind_of
|
44
|
+
create_class_settings_method :required_respond_to
|
45
|
+
create_class_settings_method :attribute_defaults
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Requires that object.snark.kind_of? String be true
|
50
|
+
# on the call to initialize.
|
51
|
+
#
|
52
|
+
# Throws a NamedArgumentException if that test fails.
|
53
|
+
#
|
54
|
+
# required_kind_of :snark => String, :boojum => Fixnum
|
55
|
+
def required_kind_of
|
56
|
+
# Dummy for rdoc
|
57
|
+
end
|
58
|
+
|
59
|
+
# Requires that the given arguments be present on the
|
60
|
+
# call to new.
|
61
|
+
#
|
62
|
+
# required_fields [:snark, :boojum]
|
63
|
+
#
|
64
|
+
# or
|
65
|
+
#
|
66
|
+
# required_fields :snark
|
67
|
+
def required_fields
|
68
|
+
# Dummy for rdoc
|
69
|
+
end
|
70
|
+
|
71
|
+
# Requires that the given objects respond to the
|
72
|
+
# method call.
|
73
|
+
#
|
74
|
+
# required_respond_to :snark => 'hunt'
|
75
|
+
#
|
76
|
+
# Raises a NamedArgumentException on failure.
|
77
|
+
def required_respond_to
|
78
|
+
# Dummy for rdoc
|
79
|
+
end
|
80
|
+
|
81
|
+
# Set defaults for the given attributes.
|
82
|
+
#
|
83
|
+
# Values can be:
|
84
|
+
#
|
85
|
+
# * A class. The #new method is called with no arguments.
|
86
|
+
# * A Proc. The proc is called with one argument.
|
87
|
+
# * []. A new array is created.
|
88
|
+
# * {}. A new hash is created.
|
89
|
+
#
|
90
|
+
# attribute_defaults :snark => lambda {|s| String.new s.to_s}
|
91
|
+
# attribute_defaults :snark => [], :boojum => ObjectTypeFromSomewhereElse
|
92
|
+
# attribute_defaults :snark => {}
|
93
|
+
def attribute_defaults
|
94
|
+
# Dummy for rdoc
|
95
|
+
end
|
96
|
+
|
97
|
+
# Set the attributes for this object. Normally called
|
98
|
+
# by initialize.
|
99
|
+
|
100
|
+
def attributes_set(args) # :nodoc:
|
101
|
+
set_default_attributes(args)
|
102
|
+
|
103
|
+
args_plus_defaults = (attribute_defaults? || {}).merge(args)
|
104
|
+
check_required_field args_plus_defaults
|
105
|
+
check_required_kind
|
106
|
+
check_required_respond_to
|
107
|
+
end
|
108
|
+
|
109
|
+
def set_default_attributes(args) # :nodoc:
|
110
|
+
defaults = {}
|
111
|
+
(attribute_defaults? || {}).each_pair do |k, v|
|
112
|
+
if Class === v
|
113
|
+
result = v.new
|
114
|
+
elsif Proc === v
|
115
|
+
result = v.call self
|
116
|
+
elsif v.class == Array and v.empty?
|
117
|
+
result = Array.new
|
118
|
+
elsif v.class == Hash and v.empty?
|
119
|
+
result = Hash.new
|
120
|
+
else
|
121
|
+
result = v
|
122
|
+
end
|
123
|
+
defaults[k] = result
|
124
|
+
end
|
125
|
+
args = defaults.merge args
|
126
|
+
args.each_pair do
|
127
|
+
|k, v|
|
128
|
+
m = "#{k}="
|
129
|
+
send m, v if respond_to? m
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# An array of field names. When an object is created
|
134
|
+
# all of these attributes must be passed. (They can be
|
135
|
+
# set to nil)
|
136
|
+
#
|
137
|
+
# Note that this can only be called as a class method.
|
138
|
+
|
139
|
+
# A hash of :fieldname => klass pairs that specify the
|
140
|
+
# required class of each of the attributes.
|
141
|
+
|
142
|
+
# Checks to make sure all the required fields
|
143
|
+
# are passed in.
|
144
|
+
#
|
145
|
+
# See also: required_fields
|
146
|
+
|
147
|
+
def check_required_field(fields_set) # :nodoc:
|
148
|
+
(required_fields? || []).each do |f|
|
149
|
+
raise ParameterRequired, "Must set parameter: " + f.to_s unless fields_set.has_key? f.to_sym
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# Checks to make sure all the fields specifed in required_kind_of
|
154
|
+
# have the right kind of objects.
|
155
|
+
#
|
156
|
+
# See also:
|
157
|
+
# * #required_kind_of
|
158
|
+
# * #set_default_attributes
|
159
|
+
|
160
|
+
def check_required_kind # :nodoc:
|
161
|
+
(required_kind_of? || {}).each_pair do |k, v|
|
162
|
+
raise WrongClass.new("Wrong class: #{k.to_s}; should have been #{v.to_s}, object is #{self.send(k).inspect}") unless v === self.send(k)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def check_required_respond_to # :nodoc:
|
167
|
+
(required_respond_to? || {}).each_pair do |k, v|
|
168
|
+
raise MustRespondTo.new("#{k} must respond to #{v}; the object is #{self.send(k).inspect}") unless self.send(k).respond_to?(v)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
# For every key/value pair in +args+, set the
|
173
|
+
# value of the attribute +key+ to +value+.
|
174
|
+
#
|
175
|
+
# class Snark
|
176
|
+
# include NamedArguments
|
177
|
+
# attr_accessor :boojum
|
178
|
+
# end
|
179
|
+
#
|
180
|
+
# s = Snark.new :boojum => 7
|
181
|
+
def initialize args = {}
|
182
|
+
if kind_of? ActiveRecord::Base
|
183
|
+
super
|
184
|
+
else
|
185
|
+
super()
|
186
|
+
end
|
187
|
+
attributes_set args
|
188
|
+
end
|
189
|
+
|
190
|
+
def option_attr_get k # :nodoc:
|
191
|
+
option_attr_storage[k]
|
192
|
+
end
|
193
|
+
|
194
|
+
def option_attr_set k, v # :nodoc:
|
195
|
+
option_attr_storage[k] = v
|
196
|
+
end
|
197
|
+
|
198
|
+
def option_attr_storage # :nodoc:
|
199
|
+
self.options ||= {}
|
200
|
+
end
|
201
|
+
|
202
|
+
def option_attrs_keys # :nodoc:
|
203
|
+
option_attr_storage.keys
|
204
|
+
end
|
205
|
+
|
206
|
+
def option_attrs_keys_set # :nodoc:
|
207
|
+
option_attrs_keys.select do |k|
|
208
|
+
option_attr_storage.include? k
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
# Class methods (methods of the class
|
213
|
+
# object itself) provided when
|
214
|
+
# NamedArguments in included.
|
215
|
+
module ClassMethods
|
216
|
+
def option_attr *array_of_names
|
217
|
+
array_of_names.each { |n|
|
218
|
+
define_method n, lambda {
|
219
|
+
option_attr_get n
|
220
|
+
}
|
221
|
+
define_method "#{n}=", lambda { |v|
|
222
|
+
option_attr_set n, v
|
223
|
+
}
|
224
|
+
}
|
225
|
+
end
|
226
|
+
|
227
|
+
def type_converter field, new_klass
|
228
|
+
alias_name = ('attribute_setter_for_' + field.to_s).to_sym
|
229
|
+
setter_method_name = (field.to_s + '=').to_sym
|
230
|
+
alias_method alias_name, setter_method_name
|
231
|
+
send :define_method, setter_method_name do |rhs|
|
232
|
+
if Integer === new_klass
|
233
|
+
v = rhs.to_i
|
234
|
+
elsif new_klass == String
|
235
|
+
v = rhs.to_s
|
236
|
+
elsif new_klass == Symbol
|
237
|
+
v = rhs.to_sym
|
238
|
+
elsif new_klass == :boolean
|
239
|
+
v = !!rhs
|
240
|
+
elsif Proc === new_klass
|
241
|
+
v = new_klass.call v
|
242
|
+
else
|
243
|
+
v = new_klass.new rhs
|
244
|
+
end
|
245
|
+
self.send alias_name, v
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
class Error < RuntimeError; end
|
251
|
+
class ParameterRequired < Error; end
|
252
|
+
class WrongClass < Error; end
|
253
|
+
class MustRespondTo < Error; end
|
254
|
+
end
|
255
|
+
|
256
|
+
# If Rails isn't around, fake ActiveRecord
|
257
|
+
module ActiveRecord; end;
|
258
|
+
class ActiveRecord::Base; end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
module NamedArguments
|
2
|
+
module ClassSettingsMixin
|
3
|
+
def self.included target
|
4
|
+
target.class_eval do
|
5
|
+
include NamedArguments::MethodExtensions
|
6
|
+
extend ClassMethods
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
include NamedArguments::MethodExtensions
|
12
|
+
|
13
|
+
def self.included target
|
14
|
+
target.class_eval do
|
15
|
+
include NamedArguments::MethodExtensions
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Allow you to define
|
20
|
+
# methods that set a class value hash
|
21
|
+
# and an accessor for that hash.
|
22
|
+
#
|
23
|
+
# Example:
|
24
|
+
#
|
25
|
+
# create_class_settings_method :settings
|
26
|
+
#
|
27
|
+
# creates:
|
28
|
+
#
|
29
|
+
# settings:: A class method that allows
|
30
|
+
# you to set variables
|
31
|
+
# settings?:: The current value of those variables
|
32
|
+
#
|
33
|
+
# class BlueCar
|
34
|
+
# create_class_settings_method :settings
|
35
|
+
# create_class_settings_method :has_these
|
36
|
+
#
|
37
|
+
# settings :color => :blue, :another_settting => 10
|
38
|
+
# settings :painted => true
|
39
|
+
# has_these :doors, :windows
|
40
|
+
# has_these :wheels
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# class Convertable < BlueCar
|
44
|
+
# has_these :poptop
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# BlueCar.color
|
48
|
+
# => :blue
|
49
|
+
#
|
50
|
+
# BlueCar.new.settings?
|
51
|
+
# => {:color => :blue, :painted => true, :another_settting => 10}
|
52
|
+
def create_class_settings_method name
|
53
|
+
# Build the class methods first
|
54
|
+
l = class_setting_lambda name
|
55
|
+
define_method_with_context name, &l
|
56
|
+
|
57
|
+
# Allow #name? to be called as an instance method
|
58
|
+
# and default its return value to nil.
|
59
|
+
# This will be replaced on any call to the
|
60
|
+
# setter.
|
61
|
+
value_name = value_field_identifier(name)
|
62
|
+
instance_method = lambda {nil}
|
63
|
+
define_method value_name, instance_method
|
64
|
+
end
|
65
|
+
|
66
|
+
protected
|
67
|
+
|
68
|
+
# Returns a lambda that will create
|
69
|
+
# two methods:
|
70
|
+
#
|
71
|
+
# A singleton method on the current object
|
72
|
+
# that takes multiple parameters and
|
73
|
+
# stores their values. This allows
|
74
|
+
# you to define methods on the class
|
75
|
+
# that will save their parameters.
|
76
|
+
# An instance method that returns those
|
77
|
+
# saved parameters
|
78
|
+
def class_setting_lambda name #:nodoc:
|
79
|
+
value_field_id = value_field_identifier name
|
80
|
+
result = lambda do
|
81
|
+
# Note that this lambda is called
|
82
|
+
# either with a single argument
|
83
|
+
# containing a hash, or an array
|
84
|
+
# of arguments.
|
85
|
+
|*args|
|
86
|
+
|
87
|
+
if args.first.kind_of? Hash
|
88
|
+
args = args.first
|
89
|
+
end
|
90
|
+
|
91
|
+
begin
|
92
|
+
current_value = self.send value_field_id
|
93
|
+
case current_value
|
94
|
+
when Array then val = merge_arrays_of_symbols current_value, args
|
95
|
+
when Hash then val = current_value.merge args
|
96
|
+
else
|
97
|
+
raise RuntimeError.new("Attempting to merge two different kinds of data")
|
98
|
+
end
|
99
|
+
rescue NoMethodError
|
100
|
+
val = args
|
101
|
+
end
|
102
|
+
|
103
|
+
# Define the class method
|
104
|
+
define_method_with_value value_field_id, val
|
105
|
+
|
106
|
+
# Define the instance method
|
107
|
+
define_method value_field_id, lambda {val}
|
108
|
+
end
|
109
|
+
result
|
110
|
+
end
|
111
|
+
|
112
|
+
def value_field_identifier name #:nodoc:
|
113
|
+
return "#{name}?"
|
114
|
+
end
|
115
|
+
|
116
|
+
def merge_arrays_of_symbols a, b #:nodoc:
|
117
|
+
result = a.map(&:to_sym) + b.map(&:to_sym)
|
118
|
+
result.uniq
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module NamedArguments
|
2
|
+
# Provides several hash utilities.
|
3
|
+
#
|
4
|
+
# Note that you need to extend your hash with this module:
|
5
|
+
#
|
6
|
+
# hash = {}
|
7
|
+
# hash.extend HashExtendedTools
|
8
|
+
# hash = hash.exclude :foo, :bar
|
9
|
+
#
|
10
|
+
# Or create a new class:
|
11
|
+
#
|
12
|
+
# class HashWithExtendedTools < Hash
|
13
|
+
# include HashExtendedTools
|
14
|
+
# end
|
15
|
+
module HashExtendedTools
|
16
|
+
# Change keys in a hash.
|
17
|
+
#
|
18
|
+
# Pass in a hash of:
|
19
|
+
#
|
20
|
+
# old_key => new_key
|
21
|
+
#
|
22
|
+
# Any keys matching +old_key+ will be
|
23
|
+
# deleted and a new entry created with
|
24
|
+
# the same value and the new key.
|
25
|
+
def switch_keys args = {}
|
26
|
+
args.each_pair do
|
27
|
+
|old_key, new_key|
|
28
|
+
if self.has_key?(old_key)
|
29
|
+
self[new_key] = self[old_key]
|
30
|
+
delete(old_key)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
# Return a new hash not including
|
37
|
+
# keys that are contained in
|
38
|
+
# +keys_to_exclude+.
|
39
|
+
#
|
40
|
+
# Keys that match entries in
|
41
|
+
# +keys_to_exclude+ are deleted if
|
42
|
+
# either they match as string or a
|
43
|
+
# symbol (created with to_sym).
|
44
|
+
def exclude *keys_to_exclude
|
45
|
+
result = self.dup
|
46
|
+
keys_to_exclude.each do |k|
|
47
|
+
result.delete k.to_s
|
48
|
+
result.delete k.to_sym
|
49
|
+
end
|
50
|
+
result
|
51
|
+
end
|
52
|
+
|
53
|
+
# Given an array of keys,
|
54
|
+
# return a hash containing
|
55
|
+
# the key/value pairs
|
56
|
+
# for the matching keys.
|
57
|
+
#
|
58
|
+
# Values that are nil are not
|
59
|
+
# returned.
|
60
|
+
def slice *slice_keys
|
61
|
+
result = {}
|
62
|
+
slice_keys.each do |k|
|
63
|
+
result[k] = self[k] unless self[k].nil?
|
64
|
+
end
|
65
|
+
result
|
66
|
+
end
|
67
|
+
|
68
|
+
# Return the given attributes as a hash containing
|
69
|
+
# attribute => value pairs.
|
70
|
+
#
|
71
|
+
# obj.a = 10
|
72
|
+
# obj.b = 20
|
73
|
+
# attributes_as_hash(:a, :b)
|
74
|
+
# => {:a => 10, :b => 20}
|
75
|
+
def attributes_as_hash *attrs
|
76
|
+
result = {}
|
77
|
+
attrs.each do |a|
|
78
|
+
v = self.send a
|
79
|
+
result[a] = v unless v.nil?
|
80
|
+
end
|
81
|
+
result
|
82
|
+
end
|
83
|
+
|
84
|
+
def symbol_keys_as_strings
|
85
|
+
sym_keys = self.keys.select {|k| k.kind_of? Symbol}
|
86
|
+
new_keys = {}
|
87
|
+
sym_keys.each {|k| new_keys[k] = k.to_s}
|
88
|
+
result = dup
|
89
|
+
result.extend HashExtendedTools
|
90
|
+
result.switch_keys new_keys
|
91
|
+
result
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module NamedArguments
|
2
|
+
# Adds two methods to a class:
|
3
|
+
#
|
4
|
+
# define_method_with_context
|
5
|
+
# define_method_with_value
|
6
|
+
module MethodExtensions
|
7
|
+
def self.included target
|
8
|
+
target.class_eval do
|
9
|
+
include ExtendedDefines
|
10
|
+
extend ExtendedDefines
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module ExtendedDefines
|
15
|
+
# Create a method out of a
|
16
|
+
# name and a lambda.
|
17
|
+
#
|
18
|
+
# Example:
|
19
|
+
#
|
20
|
+
# my_lambda = lambda {13}
|
21
|
+
# define_method_with_context :return_13, my_lambda
|
22
|
+
#
|
23
|
+
# assert 13 == self.return_13
|
24
|
+
def define_method_with_context method_name, &block
|
25
|
+
sclass = class << self; self end
|
26
|
+
sclass.send(:define_method, method_name, block)
|
27
|
+
sclass.send(:public, method_name)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Create a method out of a
|
31
|
+
# value and a name
|
32
|
+
# The method will return the value.
|
33
|
+
#
|
34
|
+
# Example:
|
35
|
+
#
|
36
|
+
# define_method_with_value :return_14, 14
|
37
|
+
#
|
38
|
+
# assert 14 == self.return_14
|
39
|
+
def define_method_with_value name, value
|
40
|
+
define_method_with_context name do
|
41
|
+
value
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def define_method_noop name
|
46
|
+
define_method_with_context name do
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
class NamedArgumentsTest < Test::Unit::TestCase
|
5
|
+
class TestClassAttributeDefaults
|
6
|
+
include NamedArguments
|
7
|
+
attr_accessor :foo, :bar
|
8
|
+
attribute_defaults :foo => 3
|
9
|
+
attribute_defaults :bar => 'bar'
|
10
|
+
end
|
11
|
+
|
12
|
+
class TestClassRequiredFields
|
13
|
+
include NamedArguments
|
14
|
+
required_fields :foo, :bar
|
15
|
+
attr_accessor :foo, :bar
|
16
|
+
end
|
17
|
+
|
18
|
+
class TestClassTypeConverter
|
19
|
+
include NamedArguments
|
20
|
+
attr_accessor :foo
|
21
|
+
type_converter :foo, String
|
22
|
+
end
|
23
|
+
|
24
|
+
# attribute_defaults :color => 'blue', :size => lambda {|s| some_method_call(s)}
|
25
|
+
# required_fields :color, :name
|
26
|
+
# required_respond_to :name => :to_s
|
27
|
+
# required_kind_of? :size => Fixnum
|
28
|
+
# type_converter :size => Fixnum
|
29
|
+
def test_attribute_defaults
|
30
|
+
o = TestClassAttributeDefaults.new
|
31
|
+
assert_equal 3, o.foo
|
32
|
+
assert_equal 'bar', o.bar
|
33
|
+
o = TestClassAttributeDefaults.new :bar => 7
|
34
|
+
assert_equal 7, o.bar
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_required_fields
|
38
|
+
assert_raises NamedArguments::ParameterRequired do
|
39
|
+
o = TestClassRequiredFields.new
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_required_respond_to
|
44
|
+
end
|
45
|
+
|
46
|
+
def type_converter
|
47
|
+
o = TestClassTypeConverter.new :foo => 3
|
48
|
+
assert_equal '3', o.foo
|
49
|
+
|
50
|
+
o = TestClassTypeConverter.new :foo => 3
|
51
|
+
assert_equal '3', o.foo
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_includes
|
55
|
+
t = TestClassTypeConverter.new
|
56
|
+
t.define_method_with_value :test_method, 7
|
57
|
+
assert_equal 7, t.test_method
|
58
|
+
end
|
59
|
+
end
|
metadata
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.4
|
3
|
+
specification_version: 1
|
4
|
+
name: named_arguments
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.0.4
|
7
|
+
date: 2007-06-03 00:00:00 -07:00
|
8
|
+
summary: The author was too lazy to write a summary
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: ryand-ruby@zenspider.com
|
12
|
+
homepage: http://www.zenspider.com/ZSS/Products/named_arguments/
|
13
|
+
rubyforge_project: named_arguments
|
14
|
+
description: The author was too lazy to write a description
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- Ryan Davis
|
31
|
+
files:
|
32
|
+
- History.txt
|
33
|
+
- Manifest.txt
|
34
|
+
- README.txt
|
35
|
+
- Rakefile
|
36
|
+
- lib/named_arguments.rb
|
37
|
+
- lib/named_arguments/class_settings_mixin.rb
|
38
|
+
- lib/named_arguments/hash_extended_tools.rb
|
39
|
+
- lib/named_arguments/method_extensions.rb
|
40
|
+
- test/unit/named_arguments_test.rb
|
41
|
+
- test/test_helper.rb
|
42
|
+
test_files:
|
43
|
+
- test/test_helper.rb
|
44
|
+
rdoc_options:
|
45
|
+
- --main
|
46
|
+
- README.txt
|
47
|
+
extra_rdoc_files:
|
48
|
+
- History.txt
|
49
|
+
- Manifest.txt
|
50
|
+
- README.txt
|
51
|
+
executables: []
|
52
|
+
|
53
|
+
extensions: []
|
54
|
+
|
55
|
+
requirements: []
|
56
|
+
|
57
|
+
dependencies:
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: hoe
|
60
|
+
version_requirement:
|
61
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: 1.2.1
|
66
|
+
version:
|