rdp-arguments 0.6
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 +22 -0
- data/Manifest.txt +12 -0
- data/README.rdoc +114 -0
- data/Rakefile +29 -0
- data/arguments.gemspec +43 -0
- data/lib/arguments/class.rb +58 -0
- data/lib/arguments/mri.rb +9 -0
- data/lib/arguments/vm.rb +21 -0
- data/lib/arguments.rb +27 -0
- data/spec/arguments_spec.rb +164 -0
- data/spec/klass.rb +63 -0
- data/spec/module.rb +9 -0
- metadata +108 -0
data/History.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
== 0.4 2009-06-30
|
2
|
+
|
3
|
+
* 1 major enhancement:
|
4
|
+
* Initial release
|
5
|
+
* Works with Ruby 1.8.6 and 1.9.1
|
6
|
+
|
7
|
+
== 0.4.2 2009-07-03
|
8
|
+
|
9
|
+
* Fixed a Bug where not passing arguments would rise try to call #key? on nil
|
10
|
+
|
11
|
+
== 0.4.3 2009-07-07
|
12
|
+
|
13
|
+
* Fixed a serious bug where default values could not be overriden by passing arguments without keyword
|
14
|
+
|
15
|
+
== 0.6 2009-08-06
|
16
|
+
|
17
|
+
* Fixed a bug where converting a block to proc argument using ampersand would blow method call
|
18
|
+
* Passing a keyword not corresponding to an argument name raises an error
|
19
|
+
* Using RubyParser in Ruby 1.9.1 instead of Regexp to extract argument names and default values
|
20
|
+
* Method definition that uses splat operator is now ignored
|
21
|
+
* Last Hash argument is not used for assigning argument values if total number of arguments has been passed
|
22
|
+
* named_arguments_for can be called passing a Class method name eg: named_args_for :instance_method, 'self.class_method'
|
data/Manifest.txt
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
= arguments
|
2
|
+
|
3
|
+
Keyword arguments support now!
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
You don't have to wait until Ruby 2.0 to get (named|keyword) arguments support.
|
8
|
+
Arguments has been tested with Ruby 1.8.6 and ruby 1.9.1 and eventually will work with JRuby (if someone is interested in contributing, I guess is possible since merb-action-args works with JRuby)
|
9
|
+
|
10
|
+
== SYNOPSIS:
|
11
|
+
|
12
|
+
require 'arguments'
|
13
|
+
|
14
|
+
class Example
|
15
|
+
def meth(a = :a, b = :b, c = :c)
|
16
|
+
[a,b,c]
|
17
|
+
end
|
18
|
+
|
19
|
+
class << self
|
20
|
+
def class_method(a = :a, b = :b, c = :c)
|
21
|
+
[a,b,c]
|
22
|
+
end
|
23
|
+
|
24
|
+
def other_class_method(a = :a, b = :b, c = :c)
|
25
|
+
[a,b,c]
|
26
|
+
end
|
27
|
+
named_args_for :class_method
|
28
|
+
end
|
29
|
+
|
30
|
+
named_args_for :meth, :'self.other_class_method'
|
31
|
+
end
|
32
|
+
|
33
|
+
nu = Example.new
|
34
|
+
nu.meth #=> [:a,:b,:c]
|
35
|
+
nu.meth(1, :c => Class) #=> [1,:b,Class]
|
36
|
+
nu.meth(:b => nil, :a => 'something') #=> ['something', nil, :c]
|
37
|
+
|
38
|
+
Example.class_method(:b => nil, :a => 'something') #=> ['something', nil, :c]
|
39
|
+
Example.other_class_method(:b => nil, :a => 'something') #=> ['something', nil, :c]
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
|
44
|
+
* #named_arguments_for is aliased as #named_args_for and #named_args
|
45
|
+
* Calling #named_args_for without arguments patches all previously declared methods in scope
|
46
|
+
* Last Hash argument is used to assign argument values unless passing all accepted arguments:
|
47
|
+
|
48
|
+
nu.meth(1, :c => 'string') #=> [1, :b, 'string']
|
49
|
+
nu.meth(1, 2, :a => 'string') #=> [1, 2, {:a => 'string'}]
|
50
|
+
|
51
|
+
* Any number of method names (Symbol or String) corresponding to existing methods can be passed
|
52
|
+
* Methods with no optionals won't be patched (will behave as usual with no named params)
|
53
|
+
* Same for methods with splatted arguments and for native methods (not declared in Ruby)
|
54
|
+
* Keyword argument take precedence over argument order:
|
55
|
+
|
56
|
+
nu.meth(10, :a => -10) #=> [-10, :b, :c]
|
57
|
+
|
58
|
+
* pasing a key not corresponding to an argument name will raise ArgumentError:
|
59
|
+
|
60
|
+
nu.meth(10, :four => -10) #=> ArgumentError: `four` is not an argument name.
|
61
|
+
|
62
|
+
== LIMITATIONS
|
63
|
+
|
64
|
+
* Performance penalty occurs only in 1.8.6 due to ParseTree use and only while calling Class#named_args\_for, penalty while calling the actuall method is neglectable.
|
65
|
+
* With Ruby 1.8.6 it can patch methods declared with eval, with 1.9.1 only methods declared in a source file.
|
66
|
+
|
67
|
+
== REQUIREMENTS:
|
68
|
+
|
69
|
+
- Ruby2Ruby 1.1.9
|
70
|
+
|
71
|
+
Ruby 1.8.6:
|
72
|
+
- ParseTree >= 3.0.3
|
73
|
+
|
74
|
+
Ruby 1.9.1
|
75
|
+
- RubyParser >= 2.0.2
|
76
|
+
|
77
|
+
== INSTALL:
|
78
|
+
|
79
|
+
sudo gem install maca-arguments –source http://gems.github.com
|
80
|
+
|
81
|
+
== LATEST CHANGES (0.6)
|
82
|
+
|
83
|
+
* Fixed a bug where converting a block to proc argument using ampersand would blow method call
|
84
|
+
* Passing a keyword not corresponding to an argument name raises an error
|
85
|
+
* Using RubyParser in Ruby 1.9.1 instead of Regexp to extract argument names and default values
|
86
|
+
* Method definition that uses splat operator is now ignored
|
87
|
+
* Last Hash argument is not used for assigning argument values if total number of arguments has been passed
|
88
|
+
* named_arguments_for can be called passing a Class method name eg: named_args_for :instance_method, 'self.class_method'
|
89
|
+
|
90
|
+
|
91
|
+
== LICENSE:
|
92
|
+
|
93
|
+
(The MIT License)
|
94
|
+
|
95
|
+
Copyright (c) 2009 Macario Ortega
|
96
|
+
|
97
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
98
|
+
a copy of this software and associated documentation files (the
|
99
|
+
'Software'), to deal in the Software without restriction, including
|
100
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
101
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
102
|
+
permit persons to whom the Software is furnished to do so, subject to
|
103
|
+
the following conditions:
|
104
|
+
|
105
|
+
The above copyright notice and this permission notice shall be
|
106
|
+
included in all copies or substantial portions of the Software.
|
107
|
+
|
108
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
109
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
110
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
111
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
112
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
113
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
114
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'hoe', '>= 2.1.0'
|
3
|
+
require 'hoe'
|
4
|
+
require 'fileutils'
|
5
|
+
require './lib/arguments'
|
6
|
+
|
7
|
+
Hoe.plugin :newgem
|
8
|
+
# Hoe.plugin :website
|
9
|
+
# Hoe.plugin :cucumberfeatures
|
10
|
+
|
11
|
+
# Generate all the Rake tasks
|
12
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
13
|
+
$hoe = Hoe.spec 'arguments' do
|
14
|
+
self.developer 'Macario Ortega', 'macarui@gmail.com'
|
15
|
+
self.rubyforge_name = self.name # TODO this is default value
|
16
|
+
self.extra_deps = [
|
17
|
+
['ruby_parser', '>= 2.0.2'],
|
18
|
+
['ParseTree', '>= 3.0.3'],
|
19
|
+
['ruby2ruby', '= 1.1.9']
|
20
|
+
]
|
21
|
+
self.homepage = 'http://github.com/maca/arguments'
|
22
|
+
end
|
23
|
+
|
24
|
+
require 'newgem/tasks'
|
25
|
+
Dir['tasks/**/*.rake'].each { |t| load t }
|
26
|
+
|
27
|
+
# TODO - want other tests/tasks run by default? Add them to the list
|
28
|
+
# remove_task :default
|
29
|
+
# task :default => [:spec, :features]
|
data/arguments.gemspec
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{rdp-arguments}
|
5
|
+
s.version = "0.6"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Macario Ortega"]
|
9
|
+
s.date = %q{2009-08-06}
|
10
|
+
s.description = %q{You don't have to wait until Ruby 2.0 to get (named|keyword) arguments support. Arguments has been tested with Ruby 1.8.6 and ruby 1.9.1 and eventually will work with JRuby (if someone is interested in contributing, I guess is possible since merb-action-args works with JRuby)}
|
11
|
+
s.email = ["macarui@gmail.com"]
|
12
|
+
s.extra_rdoc_files = ["History.txt", "Manifest.txt"]
|
13
|
+
s.files = ["History.txt", "Manifest.txt", "README.rdoc", "Rakefile", "arguments.gemspec", "lib/arguments.rb", "lib/arguments/class.rb", "lib/arguments/mri.rb", "lib/arguments/vm.rb", "spec/arguments_spec.rb", "spec/klass.rb", "spec/module.rb"]
|
14
|
+
s.has_rdoc = true
|
15
|
+
s.homepage = %q{http://github.com/maca/arguments}
|
16
|
+
s.rdoc_options = ["--main", "README.rdoc"]
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
s.rubyforge_project = %q{arguments}
|
19
|
+
s.rubygems_version = %q{1.3.1}
|
20
|
+
s.summary = %q{You don't have to wait until Ruby 2.0 to get (named|keyword) arguments support}
|
21
|
+
|
22
|
+
if s.respond_to? :specification_version then
|
23
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
24
|
+
s.specification_version = 2
|
25
|
+
|
26
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
27
|
+
s.add_runtime_dependency(%q<ruby_parser>, [">= 2.0.2"])
|
28
|
+
s.add_runtime_dependency(%q<ParseTree>, [">= 3.0.3"])
|
29
|
+
s.add_runtime_dependency(%q<ruby2ruby>, ["= 1.1.9"])
|
30
|
+
s.add_development_dependency(%q<hoe>, [">= 2.3.2"])
|
31
|
+
else
|
32
|
+
s.add_dependency(%q<ruby_parser>, [">= 2.0.2"])
|
33
|
+
s.add_dependency(%q<ParseTree>, [">= 3.0.3"])
|
34
|
+
s.add_dependency(%q<ruby2ruby>, ["= 1.1.9"])
|
35
|
+
s.add_dependency(%q<hoe>, [">= 2.3.2"])
|
36
|
+
end
|
37
|
+
else
|
38
|
+
s.add_dependency(%q<ruby_parser>, [">= 2.0.2"])
|
39
|
+
s.add_dependency(%q<ParseTree>, [">= 3.0.3"])
|
40
|
+
s.add_dependency(%q<ruby2ruby>, ["= 1.1.9"])
|
41
|
+
s.add_dependency(%q<hoe>, [">= 2.3.2"])
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Arguments
|
2
|
+
def named_arguments_for *methods
|
3
|
+
methods = instance_methods - Object.methods if methods.empty?
|
4
|
+
|
5
|
+
methods.each do |meth|
|
6
|
+
meth = meth.to_s
|
7
|
+
klass = meth.sub!(/^self./, '') ? (class << self; self; end) : self
|
8
|
+
names = Arguments.names klass, meth
|
9
|
+
next if names.empty? or names.inject(false) { |bol, pair| bol || /^\*/ === pair.first.to_s }
|
10
|
+
assigns = []
|
11
|
+
names.pop if /^&/ === names[-1][0].to_s
|
12
|
+
|
13
|
+
names.each_with_index do |name, index|
|
14
|
+
unless name.size == 1
|
15
|
+
assigns << <<-RUBY_EVAL
|
16
|
+
#{ name.first } =
|
17
|
+
if opts.key? :#{ name.first }
|
18
|
+
opts.delete :#{ name.first }
|
19
|
+
else
|
20
|
+
args.size >= #{ index + 1 } ? args[#{ index }] : #{ name.last }
|
21
|
+
end
|
22
|
+
RUBY_EVAL
|
23
|
+
else
|
24
|
+
assigns << <<-RUBY_EVAL
|
25
|
+
begin
|
26
|
+
#{ name.first } = opts.key?(:#{ name.first }) ? opts.delete(:#{ name.first }) : args.fetch(#{ index })
|
27
|
+
rescue
|
28
|
+
raise ArgumentError.new('passing `#{ name.first }` is required')
|
29
|
+
end
|
30
|
+
RUBY_EVAL
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
klass.module_eval <<-RUBY_EVAL, __FILE__, __LINE__
|
35
|
+
def __#{ meth }_with_keyword_arguments *args, &block
|
36
|
+
opts = args.last.kind_of?( Hash ) && args.size < #{ names.size } ? args.pop : {}
|
37
|
+
#{ assigns.join("\n") }
|
38
|
+
unless opts.empty?
|
39
|
+
raise ArgumentError.new("`\#{ opts.keys.join(', ') }` \#{ opts.size == 1 ? 'is not a recognized argument keyword' : 'are not recognized argument keywords' }")
|
40
|
+
end
|
41
|
+
__original_#{ meth } #{ names.collect{ |n| n.first }.join(', ') }, &block
|
42
|
+
end
|
43
|
+
|
44
|
+
alias __original_#{ meth } #{ meth }
|
45
|
+
alias #{ meth } __#{ meth }_with_keyword_arguments
|
46
|
+
RUBY_EVAL
|
47
|
+
end
|
48
|
+
end
|
49
|
+
alias :named_args_for :named_arguments_for
|
50
|
+
alias :named_args :named_arguments_for
|
51
|
+
end
|
52
|
+
|
53
|
+
class Class
|
54
|
+
include Arguments
|
55
|
+
end
|
56
|
+
class Module
|
57
|
+
include Arguments
|
58
|
+
end
|
data/lib/arguments/vm.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
gem 'ruby_parser', '>= 2.0.2'
|
2
|
+
require 'ruby_parser'
|
3
|
+
|
4
|
+
module Arguments
|
5
|
+
class PermissiveRubyParser < RubyParser
|
6
|
+
def on_error t, val, vstack
|
7
|
+
@rescue = vstack.first
|
8
|
+
end
|
9
|
+
|
10
|
+
def parse str, file = "(string)"
|
11
|
+
super || @rescue
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.ast_for_method klass, method
|
16
|
+
source, line = klass.instance_method(method).source_location
|
17
|
+
str = IO.readlines( source )[ (line-1)..-1 ].join
|
18
|
+
ast = PermissiveRubyParser.new.parse( str )
|
19
|
+
ast.assoc( :defn ) or ast
|
20
|
+
end
|
21
|
+
end
|
data/lib/arguments.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
gem 'ruby2ruby', '= 1.1.9'
|
2
|
+
require 'ruby2ruby'
|
3
|
+
|
4
|
+
$:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
5
|
+
require 'arguments/class'
|
6
|
+
|
7
|
+
RUBY_VERSION.to_f >= 1.9 ? require( 'arguments/vm' ) : require( 'arguments/mri' )
|
8
|
+
|
9
|
+
module Arguments
|
10
|
+
VERSION = '0.6'
|
11
|
+
|
12
|
+
def self.names klass, method
|
13
|
+
args = ast_for_method(klass, method).assoc(:args)
|
14
|
+
args = args[1..-1]
|
15
|
+
|
16
|
+
return [] if args.empty? or args.last.is_a?(Symbol)
|
17
|
+
vals = args.pop[1..-1]
|
18
|
+
|
19
|
+
args.collect do |arg|
|
20
|
+
if val = vals.find{ |v| v[1] == arg }
|
21
|
+
[arg, Ruby2Ruby.new.process(val.last)]
|
22
|
+
else
|
23
|
+
[arg]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
require "#{ dir = File.dirname __FILE__ }/../lib/arguments"
|
2
|
+
require 'benchmark'
|
3
|
+
|
4
|
+
# TODO: Refactor specs for clarity and better coverage
|
5
|
+
describe Arguments do
|
6
|
+
|
7
|
+
before do
|
8
|
+
Object.send(:remove_const, 'Klass') rescue nil
|
9
|
+
load "#{ dir }/klass.rb"
|
10
|
+
@instance = Klass.new
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should not respond to named_arguments" do
|
14
|
+
lambda { Klass.new.send( :named_arguments_for ) }.should raise_error( NoMethodError )
|
15
|
+
end
|
16
|
+
|
17
|
+
it "shouldn't break defaults" do
|
18
|
+
@instance.two(1).should == [1, 2, Klass.new]
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should allow passing named argument" do
|
22
|
+
Klass.send( :named_arguments_for, :two )
|
23
|
+
@instance.two(1, :three => 3).should == [1, 2, 3]
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should raise ArgumentError if not passing required params" do
|
27
|
+
Klass.send( :named_arguments_for, :two )
|
28
|
+
error =
|
29
|
+
begin
|
30
|
+
@instance.two( :three => 3 )
|
31
|
+
rescue ArgumentError => e
|
32
|
+
e
|
33
|
+
end
|
34
|
+
error.to_s.should == "passing `one` is required"
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should override passed value with hash" do
|
38
|
+
Klass.send( :named_arguments_for, :two )
|
39
|
+
@instance.two( :one => nil ).should == [nil, 2, Klass.new]
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should allow for class arguments" do
|
43
|
+
Klass.send( :named_arguments_for, :defaults_with_class)
|
44
|
+
@instance.defaults_with_class(1, 3).should == 3
|
45
|
+
@instance.defaults_with_class(:a => 3).should == 3
|
46
|
+
require '_dbg'
|
47
|
+
@instance.defaults_with_class().should == 3
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should allow overriding with nil" do
|
51
|
+
Klass.send( :named_arguments_for, :two )
|
52
|
+
@instance.two( 1, :three => nil ).should == [1, 2, nil]
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should pass block" do
|
56
|
+
Klass.send( :named_arguments_for, :with_block )
|
57
|
+
@instance.with_block( 1, :three => nil, :two => 'something' ){ :block }.should == [1, 'something', nil, :block]
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should patch methods that accept proc as argument" do
|
61
|
+
Klass.send( :named_arguments_for, :with_block2 )
|
62
|
+
@instance.with_block2(1, :three => nil, :two => 'something'){ :block }.should == [1, 'something', nil, :block]
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should override defaults on standard passing" do
|
66
|
+
Klass.send( :named_arguments_for, :asr )
|
67
|
+
@instance.asr(0, 1, :curve => 3).should == [0, 1, 1, 3]
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should work with class methods" do
|
71
|
+
(class << Klass; self; end).send( :named_arguments_for, :k_method )
|
72
|
+
Klass.k_method(:d => :d).should == [1, 2, 3, :d]
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should override defaults on standard passing" do
|
76
|
+
Klass.send( :named_arguments_for, 'self.k_method' )
|
77
|
+
Klass.k_method(:d => :d).should == [1, 2, 3, :d]
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should not use options if all arguments are passed" do
|
81
|
+
Klass.send( :named_arguments_for, :two )
|
82
|
+
@instance.two( 1, 2, :three => nil ).should == [1, 2, {:three => nil}]
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should raise ArgumentError if passing a not recoginized keyword" do
|
86
|
+
Klass.send( :named_arguments_for, :two )
|
87
|
+
error =
|
88
|
+
begin
|
89
|
+
@instance.two( 1, :four => nil )
|
90
|
+
rescue ArgumentError => e
|
91
|
+
e
|
92
|
+
end
|
93
|
+
error.to_s.should == "`four` is not a recognized argument keyword"
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should raise ArgumentError if passing recoginized keywords" do
|
97
|
+
Klass.send( :named_arguments_for, :two )
|
98
|
+
error =
|
99
|
+
begin
|
100
|
+
@instance.two( 1, :four => nil, :five => nil )
|
101
|
+
rescue ArgumentError => e
|
102
|
+
e
|
103
|
+
end
|
104
|
+
error.to_s.should == "`four, five` are not recognized argument keywords"
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should not patch methods that accept no args" do
|
108
|
+
Klass.send( :named_arguments_for, :no_args )
|
109
|
+
lambda { @instance.no_args(1) }.should raise_error(ArgumentError)
|
110
|
+
@instance.no_args.should be_nil
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should not patch methods that use splatter op" do
|
114
|
+
Klass.send( :named_arguments_for, :splatted )
|
115
|
+
@instance.splatted(1, :args => 1).should == [1, {:args => 1}]
|
116
|
+
|
117
|
+
Klass.send( :named_arguments_for, :splatted2 )
|
118
|
+
@instance.splatted2(:a => 1, :"*rest" => 3).should == [{:a => 1, :'*rest' => 3}, []]
|
119
|
+
|
120
|
+
Klass.send( :named_arguments_for, :splatted3 )
|
121
|
+
@instance.splatted3(:a => 1, :"*args" => 3).should == [{:a => 1, :"*args" => 3}, []]
|
122
|
+
@instance.splatted3(1, :b => 2, :args => 1).should == [1, [{:b => 2, :args => 1}]]
|
123
|
+
|
124
|
+
Klass.send( :named_arguments_for, :splatted4 )
|
125
|
+
@instance.splatted4(1, :b => 2, :args => 1).should == [1, {:b => 2, :args => 1}, []]
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should not patch methods with no optionals" do
|
129
|
+
Klass.send( :named_arguments_for, :no_opts )
|
130
|
+
@instance.method(:no_opts).arity.should == 3
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should patch all methods" do
|
134
|
+
Klass.send( :named_args )
|
135
|
+
@instance.two(1, :three => 3).should == [1, 2, 3]
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should benchmark without hack" do
|
139
|
+
puts Benchmark.measure {
|
140
|
+
1_000.times do
|
141
|
+
@instance.with_block( 1, :three => nil ){ :block }
|
142
|
+
end
|
143
|
+
}
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should work with modules" do
|
147
|
+
require 'module.rb'
|
148
|
+
TestMod.send(:named_arguments_for, :go)
|
149
|
+
IncludesTestMod.new.go(1,2).should == 2
|
150
|
+
IncludesTestMod.new.go(:a => 1, :b => 2).should == 2
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
it "should benchmark with hack" do
|
155
|
+
puts Benchmark.measure {
|
156
|
+
Klass.send( :named_arguments_for, :with_block )
|
157
|
+
}
|
158
|
+
puts Benchmark.measure {
|
159
|
+
1_000.times do
|
160
|
+
@instance.with_block( 1, :three => nil ){ :block }
|
161
|
+
end
|
162
|
+
}
|
163
|
+
end
|
164
|
+
end
|
data/spec/klass.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
class Klass
|
2
|
+
def three one = 1, two = 2, three = 3
|
3
|
+
[one, two, three]
|
4
|
+
end
|
5
|
+
|
6
|
+
def two one, two = 2, three = Klass.new
|
7
|
+
[one, two, three]
|
8
|
+
end
|
9
|
+
|
10
|
+
def with_block one, two = 2, three = 3
|
11
|
+
[one, two, three, yield]
|
12
|
+
end
|
13
|
+
|
14
|
+
def with_block2 one, two = 2, three = 3, &action
|
15
|
+
[one, two, three, action.call]
|
16
|
+
end
|
17
|
+
|
18
|
+
def asr attackTime = 3, sustainLevel = 2, releaseTime = 1, curve = 0
|
19
|
+
[attackTime, sustainLevel, releaseTime, curve]
|
20
|
+
end
|
21
|
+
|
22
|
+
@@go = 3
|
23
|
+
def defaults_with_class b = 1, a = @@go
|
24
|
+
a
|
25
|
+
end
|
26
|
+
|
27
|
+
def no_args
|
28
|
+
end
|
29
|
+
|
30
|
+
def splatted *args
|
31
|
+
args
|
32
|
+
end
|
33
|
+
|
34
|
+
def splatted2 a=1, *rest
|
35
|
+
[a, rest]
|
36
|
+
end
|
37
|
+
|
38
|
+
def splatted3 a, *rest
|
39
|
+
[a, rest]
|
40
|
+
end
|
41
|
+
|
42
|
+
def splatted4 a, b=1, *rest
|
43
|
+
[a, b, rest]
|
44
|
+
end
|
45
|
+
|
46
|
+
def no_opts a, b, c
|
47
|
+
[a, b, c]
|
48
|
+
end
|
49
|
+
|
50
|
+
class << self
|
51
|
+
def asr attackTime = 3, sustainLevel = 2, releaseTime = 1, curve = 0
|
52
|
+
[attackTime, sustainLevel, releaseTime, curve]
|
53
|
+
end
|
54
|
+
|
55
|
+
def k_method a = 1, b = 2, c = 3, d = 4
|
56
|
+
[a, b, c, d]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def == other
|
61
|
+
self.class == other.class
|
62
|
+
end
|
63
|
+
end
|
data/spec/module.rb
ADDED
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rdp-arguments
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "0.6"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Macario Ortega
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-08-06 00:00:00 -06:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: ruby_parser
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 2.0.2
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: ParseTree
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 3.0.3
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: ruby2ruby
|
37
|
+
type: :runtime
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - "="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 1.1.9
|
44
|
+
version:
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: hoe
|
47
|
+
type: :development
|
48
|
+
version_requirement:
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 2.3.2
|
54
|
+
version:
|
55
|
+
description: You don't have to wait until Ruby 2.0 to get (named|keyword) arguments support. Arguments has been tested with Ruby 1.8.6 and ruby 1.9.1 and eventually will work with JRuby (if someone is interested in contributing, I guess is possible since merb-action-args works with JRuby)
|
56
|
+
email:
|
57
|
+
- macarui@gmail.com
|
58
|
+
executables: []
|
59
|
+
|
60
|
+
extensions: []
|
61
|
+
|
62
|
+
extra_rdoc_files:
|
63
|
+
- History.txt
|
64
|
+
- Manifest.txt
|
65
|
+
files:
|
66
|
+
- History.txt
|
67
|
+
- Manifest.txt
|
68
|
+
- README.rdoc
|
69
|
+
- Rakefile
|
70
|
+
- arguments.gemspec
|
71
|
+
- lib/arguments.rb
|
72
|
+
- lib/arguments/class.rb
|
73
|
+
- lib/arguments/mri.rb
|
74
|
+
- lib/arguments/vm.rb
|
75
|
+
- spec/arguments_spec.rb
|
76
|
+
- spec/klass.rb
|
77
|
+
- spec/module.rb
|
78
|
+
has_rdoc: true
|
79
|
+
homepage: http://github.com/maca/arguments
|
80
|
+
licenses: []
|
81
|
+
|
82
|
+
post_install_message:
|
83
|
+
rdoc_options:
|
84
|
+
- --main
|
85
|
+
- README.rdoc
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: "0"
|
93
|
+
version:
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: "0"
|
99
|
+
version:
|
100
|
+
requirements: []
|
101
|
+
|
102
|
+
rubyforge_project: arguments
|
103
|
+
rubygems_version: 1.3.5
|
104
|
+
signing_key:
|
105
|
+
specification_version: 2
|
106
|
+
summary: You don't have to wait until Ruby 2.0 to get (named|keyword) arguments support
|
107
|
+
test_files: []
|
108
|
+
|