namedarguments 0.0.3 → 0.0.5
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 -4
- data/Manifest.txt +10 -10
- data/README.txt +48 -52
- data/Rakefile +9 -4
- data/lib/named_arguments.rb +39 -36
- 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 +23 -19
- data/bin/named_arguments +0 -0
- data/lib/class_settings_mixin.rb +0 -113
- data/lib/hash_extended_tools.rb +0 -81
- data/lib/singleton_creator_mixin.rb +0 -29
- data/test/test_named_arguments.rb +0 -0
data/History.txt
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
== 0.0
|
2
|
-
|
3
|
-
* 1 major enhancement
|
4
|
-
*
|
1
|
+
== 1.0.0 / 2007-06-03
|
2
|
+
|
3
|
+
* 1 major enhancement
|
4
|
+
* Birthday!
|
5
|
+
|
data/Manifest.txt
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
History.txt
|
2
|
-
Manifest.txt
|
3
|
-
README.txt
|
4
|
-
Rakefile
|
5
|
-
|
6
|
-
lib/named_arguments.rb
|
7
|
-
lib/hash_extended_tools.rb
|
8
|
-
lib/
|
9
|
-
|
10
|
-
test/
|
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
CHANGED
@@ -1,52 +1,48 @@
|
|
1
|
-
|
2
|
-
by
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
== FEATURES/PROBLEMS:
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
==
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
50
|
-
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
51
|
-
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
52
|
-
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
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
CHANGED
@@ -1,12 +1,17 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
1
3
|
require 'rubygems'
|
2
4
|
require 'hoe'
|
3
5
|
require './lib/named_arguments.rb'
|
4
6
|
|
5
7
|
Hoe.new('namedarguments', NamedArguments::VERSION) do |p|
|
6
|
-
p.
|
7
|
-
p.author =
|
8
|
-
p.email = '
|
9
|
-
p.
|
8
|
+
p.rubyforge_name = 'namedarguments'
|
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")
|
10
13
|
# p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
|
11
14
|
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
12
15
|
end
|
16
|
+
|
17
|
+
# vim: syntax=Ruby
|
data/lib/named_arguments.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/
|
2
|
-
require File.dirname(__FILE__) + '/hash_extended_tools'
|
3
|
-
require File.dirname(__FILE__) + '/
|
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
4
|
|
5
5
|
# Adds the following features to a class:
|
6
6
|
#
|
@@ -27,14 +27,24 @@ require File.dirname(__FILE__) + '/singleton_creator_mixin'
|
|
27
27
|
#
|
28
28
|
# = See also
|
29
29
|
#
|
30
|
-
# See
|
30
|
+
# See ClassMethods for more methods:
|
31
31
|
#
|
32
|
-
# *
|
33
|
-
# *
|
32
|
+
# * ClassMethods#type_converter
|
33
|
+
# * ClassMethods#option_attr
|
34
34
|
module NamedArguments
|
35
|
-
VERSION = '0.0.
|
35
|
+
VERSION = '0.0.5'
|
36
36
|
|
37
|
-
|
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
|
38
48
|
|
39
49
|
# Requires that object.snark.kind_of? String be true
|
40
50
|
# on the call to initialize.
|
@@ -84,15 +94,6 @@ module NamedArguments
|
|
84
94
|
# Dummy for rdoc
|
85
95
|
end
|
86
96
|
|
87
|
-
def self.included target # :nodoc:
|
88
|
-
target.send :include, ClassSettingsMixin
|
89
|
-
target.send :extend, NamedArgumentsClassMethods
|
90
|
-
target.send :create_class_settings_method, :required_fields
|
91
|
-
target.send :create_class_settings_method, :required_kind_of
|
92
|
-
target.send :create_class_settings_method, :required_respond_to
|
93
|
-
target.send :create_class_settings_method, :attribute_defaults
|
94
|
-
end
|
95
|
-
|
96
97
|
# Set the attributes for this object. Normally called
|
97
98
|
# by initialize.
|
98
99
|
|
@@ -108,9 +109,9 @@ module NamedArguments
|
|
108
109
|
def set_default_attributes(args) # :nodoc:
|
109
110
|
defaults = {}
|
110
111
|
(attribute_defaults? || {}).each_pair do |k, v|
|
111
|
-
if v
|
112
|
+
if Class === v
|
112
113
|
result = v.new
|
113
|
-
elsif v
|
114
|
+
elsif Proc === v
|
114
115
|
result = v.call self
|
115
116
|
elsif v.class == Array and v.empty?
|
116
117
|
result = Array.new
|
@@ -124,7 +125,8 @@ module NamedArguments
|
|
124
125
|
args = defaults.merge args
|
125
126
|
args.each_pair do
|
126
127
|
|k, v|
|
127
|
-
|
128
|
+
m = "#{k}="
|
129
|
+
send m, v if respond_to? m
|
128
130
|
end
|
129
131
|
end
|
130
132
|
|
@@ -143,9 +145,8 @@ module NamedArguments
|
|
143
145
|
# See also: required_fields
|
144
146
|
|
145
147
|
def check_required_field(fields_set) # :nodoc:
|
146
|
-
(required_fields? || []).each do
|
147
|
-
|
148
|
-
raise NamedArgumentException.new("Must set parameter: " + f.to_s) unless fields_set.has_key? f.to_sym
|
148
|
+
(required_fields? || []).each do |f|
|
149
|
+
raise ParameterRequired, "Must set parameter: " + f.to_s unless fields_set.has_key? f.to_sym
|
149
150
|
end
|
150
151
|
end
|
151
152
|
|
@@ -157,16 +158,14 @@ module NamedArguments
|
|
157
158
|
# * #set_default_attributes
|
158
159
|
|
159
160
|
def check_required_kind # :nodoc:
|
160
|
-
(required_kind_of? || {}).each_pair do
|
161
|
-
|
162
|
-
raise NamedArgumentException.new("Wrong class: #{k.to_s}; should have been #{v.to_s}, object is #{self.send(k).inspect}") unless self.send(k).kind_of?(v)
|
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
163
|
end
|
164
164
|
end
|
165
165
|
|
166
166
|
def check_required_respond_to # :nodoc:
|
167
|
-
(required_respond_to? || {}).each_pair do
|
168
|
-
|
169
|
-
raise NamedArgumentException.new("#{k} must respond to #{v}; the object is #{self.send(k).inspect}") unless self.send(k).respond_to?(v)
|
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)
|
170
169
|
end
|
171
170
|
end
|
172
171
|
|
@@ -186,7 +185,6 @@ module NamedArguments
|
|
186
185
|
super()
|
187
186
|
end
|
188
187
|
attributes_set args
|
189
|
-
yield self if block_given?
|
190
188
|
end
|
191
189
|
|
192
190
|
def option_attr_get k # :nodoc:
|
@@ -214,7 +212,7 @@ module NamedArguments
|
|
214
212
|
# Class methods (methods of the class
|
215
213
|
# object itself) provided when
|
216
214
|
# NamedArguments in included.
|
217
|
-
module
|
215
|
+
module ClassMethods
|
218
216
|
def option_attr *array_of_names
|
219
217
|
array_of_names.each { |n|
|
220
218
|
define_method n, lambda {
|
@@ -231,7 +229,7 @@ module NamedArguments
|
|
231
229
|
setter_method_name = (field.to_s + '=').to_sym
|
232
230
|
alias_method alias_name, setter_method_name
|
233
231
|
send :define_method, setter_method_name do |rhs|
|
234
|
-
if
|
232
|
+
if Integer === new_klass
|
235
233
|
v = rhs.to_i
|
236
234
|
elsif new_klass == String
|
237
235
|
v = rhs.to_s
|
@@ -239,7 +237,7 @@ module NamedArguments
|
|
239
237
|
v = rhs.to_sym
|
240
238
|
elsif new_klass == :boolean
|
241
239
|
v = !!rhs
|
242
|
-
elsif new_klass
|
240
|
+
elsif Proc === new_klass
|
243
241
|
v = new_klass.call v
|
244
242
|
else
|
245
243
|
v = new_klass.new rhs
|
@@ -248,8 +246,13 @@ module NamedArguments
|
|
248
246
|
end
|
249
247
|
end
|
250
248
|
end
|
249
|
+
|
250
|
+
class Error < RuntimeError; end
|
251
|
+
class ParameterRequired < Error; end
|
252
|
+
class WrongClass < Error; end
|
253
|
+
class MustRespondTo < Error; end
|
251
254
|
end
|
252
255
|
|
253
|
-
#
|
254
|
-
|
255
|
-
end
|
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
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.
|
2
|
+
rubygems_version: 0.9.4
|
3
3
|
specification_version: 1
|
4
4
|
name: namedarguments
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.0.
|
7
|
-
date:
|
8
|
-
summary:
|
6
|
+
version: 0.0.5
|
7
|
+
date: 2007-06-03 00:00:00 -07:00
|
8
|
+
summary: The author was too lazy to write a summary
|
9
9
|
require_paths:
|
10
10
|
- lib
|
11
|
-
email:
|
11
|
+
email: ryand-ruby@zenspider.com
|
12
12
|
homepage: http://www.zenspider.com/ZSS/Products/namedarguments/
|
13
13
|
rubyforge_project: namedarguments
|
14
|
-
description:
|
14
|
+
description: The author was too lazy to write a description
|
15
15
|
autorequire:
|
16
16
|
default_executable:
|
17
17
|
bindir: bin
|
@@ -25,27 +25,31 @@ required_ruby_version: !ruby/object:Gem::Version::Requirement
|
|
25
25
|
platform: ruby
|
26
26
|
signing_key:
|
27
27
|
cert_chain:
|
28
|
+
post_install_message:
|
28
29
|
authors:
|
29
|
-
-
|
30
|
+
- Ryan Davis
|
30
31
|
files:
|
31
32
|
- History.txt
|
32
33
|
- Manifest.txt
|
33
34
|
- README.txt
|
34
35
|
- Rakefile
|
35
|
-
- bin/named_arguments
|
36
36
|
- lib/named_arguments.rb
|
37
|
-
- lib/
|
38
|
-
- lib/
|
39
|
-
- lib/
|
40
|
-
- test/
|
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
|
41
42
|
test_files:
|
42
|
-
- test/
|
43
|
-
rdoc_options:
|
44
|
-
|
45
|
-
|
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: []
|
46
52
|
|
47
|
-
executables:
|
48
|
-
- named_arguments
|
49
53
|
extensions: []
|
50
54
|
|
51
55
|
requirements: []
|
@@ -58,5 +62,5 @@ dependencies:
|
|
58
62
|
requirements:
|
59
63
|
- - ">="
|
60
64
|
- !ruby/object:Gem::Version
|
61
|
-
version: 1.1
|
65
|
+
version: 1.2.1
|
62
66
|
version:
|
data/bin/named_arguments
DELETED
File without changes
|
data/lib/class_settings_mixin.rb
DELETED
@@ -1,113 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/singleton_creator_mixin'
|
2
|
-
|
3
|
-
module ClassSettingsMixin
|
4
|
-
def self.included target
|
5
|
-
target.send :extend, ClassSettingsMixinClassMethods
|
6
|
-
end
|
7
|
-
end
|
8
|
-
|
9
|
-
module ClassSettingsMixinClassMethods
|
10
|
-
include SingletonMethodCreatorMixin
|
11
|
-
|
12
|
-
# Allow you to define
|
13
|
-
# methods that set a class value hash
|
14
|
-
# and an accessor for that hash.
|
15
|
-
#
|
16
|
-
# Example:
|
17
|
-
#
|
18
|
-
# create_class_settings_method :settings
|
19
|
-
#
|
20
|
-
# creates:
|
21
|
-
#
|
22
|
-
# settings:: A class method that allows
|
23
|
-
# you to set variables
|
24
|
-
# settings?:: The current value of those variables
|
25
|
-
#
|
26
|
-
# class BlueCar
|
27
|
-
# create_class_settings_method :settings
|
28
|
-
# create_class_settings_method :has_these
|
29
|
-
#
|
30
|
-
# settings :color => :blue, :another_settting => 10
|
31
|
-
# settings :painted => true
|
32
|
-
# has_these :doors, :windows
|
33
|
-
# has_these :wheels
|
34
|
-
# end
|
35
|
-
#
|
36
|
-
# class Convertable < BlueCar
|
37
|
-
# has_these :poptop
|
38
|
-
# end
|
39
|
-
#
|
40
|
-
# BlueCar.color
|
41
|
-
# => :blue
|
42
|
-
#
|
43
|
-
# BlueCar.new.settings?
|
44
|
-
# => {:color => :blue, :painted => true, :another_settting => 10}
|
45
|
-
def create_class_settings_method name
|
46
|
-
# Build the class methods first
|
47
|
-
l = class_setting_lambda name
|
48
|
-
create_singleton_method name, l
|
49
|
-
|
50
|
-
# Allow #name? to be called as an instance method
|
51
|
-
# and default its return value to nil.
|
52
|
-
# This will be replaced on any call to the
|
53
|
-
# setter.
|
54
|
-
value_name = value_field_identifier(name)
|
55
|
-
instance_method = lambda {nil}
|
56
|
-
define_method value_name, instance_method
|
57
|
-
end
|
58
|
-
|
59
|
-
protected
|
60
|
-
|
61
|
-
# Returns a lambda that will create
|
62
|
-
# two methods:
|
63
|
-
#
|
64
|
-
# A singleton method on the current object
|
65
|
-
# that takes multiple parameters and
|
66
|
-
# stores their values. This allows
|
67
|
-
# you to define methods on the class
|
68
|
-
# that will save their parameters.
|
69
|
-
# An instance method that returns those
|
70
|
-
# saved parameters
|
71
|
-
def class_setting_lambda name #:nodoc:
|
72
|
-
value_field_id = value_field_identifier name
|
73
|
-
result = lambda do
|
74
|
-
# Note that this lambda is called
|
75
|
-
# either with a single argument
|
76
|
-
# containing a hash, or an array
|
77
|
-
# of arguments.
|
78
|
-
|*args|
|
79
|
-
|
80
|
-
if args.first.kind_of? Hash
|
81
|
-
args = args.first
|
82
|
-
end
|
83
|
-
|
84
|
-
begin
|
85
|
-
current_value = self.send value_field_id
|
86
|
-
case current_value
|
87
|
-
when Array then val = merge_arrays_of_symbols current_value, args
|
88
|
-
when Hash then val = current_value.merge args
|
89
|
-
else
|
90
|
-
raise RuntimeError.new("Attempting to merge two different kinds of data")
|
91
|
-
end
|
92
|
-
rescue NoMethodError
|
93
|
-
val = args
|
94
|
-
end
|
95
|
-
|
96
|
-
# Define the class method
|
97
|
-
create_singleton_value_method value_field_id, val
|
98
|
-
|
99
|
-
# Define the instance method
|
100
|
-
define_method value_field_id, lambda {val}
|
101
|
-
end
|
102
|
-
result
|
103
|
-
end
|
104
|
-
|
105
|
-
def value_field_identifier name #:nodoc:
|
106
|
-
return "#{name}?"
|
107
|
-
end
|
108
|
-
|
109
|
-
def merge_arrays_of_symbols a, b #:nodoc:
|
110
|
-
result = a.map(&:to_sym) + b.map(&:to_sym)
|
111
|
-
result.uniq
|
112
|
-
end
|
113
|
-
end
|
data/lib/hash_extended_tools.rb
DELETED
@@ -1,81 +0,0 @@
|
|
1
|
-
# Provides several hash utilities.
|
2
|
-
#
|
3
|
-
# Note that you need to extend your hash with this module:
|
4
|
-
#
|
5
|
-
# hash = {}
|
6
|
-
# hash.extend HashExtendedTools
|
7
|
-
# hash = hash.exclude :foo, :bar
|
8
|
-
#
|
9
|
-
# Or create a new class:
|
10
|
-
#
|
11
|
-
# class HashWithExtendedTools < Hash
|
12
|
-
# include HashExtendedTools
|
13
|
-
# end
|
14
|
-
module HashExtendedTools
|
15
|
-
# Change keys in a hash.
|
16
|
-
#
|
17
|
-
# Pass in a hash of:
|
18
|
-
#
|
19
|
-
# old_key => new_key
|
20
|
-
#
|
21
|
-
# Any keys matching +old_key+ will be
|
22
|
-
# deleted and a new entry created with
|
23
|
-
# the same value and the new key.
|
24
|
-
def switch_keys args = {}
|
25
|
-
args.each_pair do
|
26
|
-
|old_key, new_key|
|
27
|
-
if self.has_key?(old_key)
|
28
|
-
self[new_key] = self[old_key]
|
29
|
-
delete(old_key)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
# Return a new hash not including
|
35
|
-
# keys that are contained in
|
36
|
-
# +keys_to_exclude+.
|
37
|
-
#
|
38
|
-
# Keys that match entries in
|
39
|
-
# +keys_to_exclude+ are deleted if
|
40
|
-
# either they match as string or a
|
41
|
-
# symbol (created with to_sym).
|
42
|
-
def exclude *keys_to_exclude
|
43
|
-
result = self.dup
|
44
|
-
keys_to_exclude.each do |k|
|
45
|
-
result.delete k.to_s
|
46
|
-
result.delete k.to_sym
|
47
|
-
end
|
48
|
-
result
|
49
|
-
end
|
50
|
-
|
51
|
-
# Given an array of keys,
|
52
|
-
# return a hash containing
|
53
|
-
# the key/value pairs
|
54
|
-
# for the matching keys.
|
55
|
-
#
|
56
|
-
# Values that are nil are not
|
57
|
-
# returned.
|
58
|
-
def slice *slice_keys
|
59
|
-
result = {}
|
60
|
-
slice_keys.each do |k|
|
61
|
-
result[k] = self[k] unless self[k].nil?
|
62
|
-
end
|
63
|
-
result
|
64
|
-
end
|
65
|
-
|
66
|
-
# Return the given attributes as a hash containing
|
67
|
-
# attribute => value pairs.
|
68
|
-
#
|
69
|
-
# obj.a = 10
|
70
|
-
# obj.b = 20
|
71
|
-
# attributes_as_hash(:a, :b)
|
72
|
-
# => {:a => 10, :b => 20}
|
73
|
-
def attributes_as_hash *attrs
|
74
|
-
result = {}
|
75
|
-
attrs.each do |a|
|
76
|
-
v = self.send a
|
77
|
-
result[a] = v unless v.nil?
|
78
|
-
end
|
79
|
-
result
|
80
|
-
end
|
81
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
module SingletonMethodCreatorMixin
|
2
|
-
# Create a method out of a
|
3
|
-
# name and a lambda.
|
4
|
-
#
|
5
|
-
# Example:
|
6
|
-
#
|
7
|
-
# my_lambda = lambda {13}
|
8
|
-
# create_singleton_method :return_13, my_lambda
|
9
|
-
#
|
10
|
-
# assert 13 == self.return_13
|
11
|
-
def create_singleton_method method_name, lambda_obj
|
12
|
-
sclass = class << self; self end
|
13
|
-
sclass.send(:define_method, method_name, lambda_obj)
|
14
|
-
sclass.send(:public, method_name)
|
15
|
-
end
|
16
|
-
|
17
|
-
# Create a method out of a
|
18
|
-
# value and a name
|
19
|
-
# The method will return the value.
|
20
|
-
#
|
21
|
-
# Example:
|
22
|
-
#
|
23
|
-
# create_singleton_value_method :return_14, 14
|
24
|
-
#
|
25
|
-
# assert 14 == self.return_14
|
26
|
-
def create_singleton_value_method name, value
|
27
|
-
create_singleton_method(name, lambda { value })
|
28
|
-
end
|
29
|
-
end
|
File without changes
|