rogerdpack-arguments 0.4.3.3 → 0.4.7.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +9 -2
- data/lib/arguments/class.rb +12 -26
- data/lib/arguments/mri.rb +4 -6
- data/lib/arguments/vm.rb +4 -1
- data/lib/arguments.rb +4 -1
- data/spec/arguments_spec.rb +33 -4
- data/spec/klass.rb +24 -1
- metadata +3 -2
data/README.rdoc
CHANGED
@@ -34,9 +34,16 @@ Arguments has been tested with Ruby 1.8.6 and ruby 1.9.1 and eventually will wor
|
|
34
34
|
Example.class_method(:b => nil, :a => 'something') #=> ['something', nil, :c]
|
35
35
|
|
36
36
|
|
37
|
-
Note: Keyword argument take precedence over argument order:
|
38
37
|
|
39
|
-
|
38
|
+
* #named_arguments_for is aliased as #named_args_for and #named_args
|
39
|
+
* Calling #named_args_for without arguments patches all previously declared methods in scope
|
40
|
+
* Any number of method names (Symbol or String) corresponding to existing methods can be passed
|
41
|
+
* Methods with no optionals won't be patched (will behave as usual with no named params)
|
42
|
+
* Same for methods with splatted arguments and for native methods (not declared in Ruby)
|
43
|
+
* Keyword argument take precedence over argument order:
|
44
|
+
|
45
|
+
nu.meth(10, :a => -10) #=> [-10, :b, :c]
|
46
|
+
|
40
47
|
|
41
48
|
== LIMITATIONS
|
42
49
|
|
data/lib/arguments/class.rb
CHANGED
@@ -1,18 +1,15 @@
|
|
1
|
-
|
2
|
-
class BinaryMethodError < Exception; end
|
3
|
-
|
4
|
-
module NamedArgs
|
5
|
-
|
1
|
+
class Class
|
6
2
|
def named_arguments_for *methods
|
7
|
-
methods.
|
8
|
-
|
9
|
-
|
10
|
-
|
3
|
+
methods = instance_methods - Object.methods if methods.empty?
|
4
|
+
|
5
|
+
methods.each do |meth|
|
6
|
+
names = Arguments.names self, meth
|
7
|
+
next if names.empty? || names.any?{|name| name[0] == :"*args"}
|
11
8
|
|
9
|
+
assigns = []
|
12
10
|
names.each_with_index do |name, index|
|
13
11
|
unless name.size == 1
|
14
12
|
# optionals
|
15
|
-
assigns << "#{ name.first } = opts.key?(:#{ name.first }) ? opts[:#{ name.first }] : args.fetch(#{ index },#{ name.last })"
|
16
13
|
assigns << <<-RUBY_EVAL
|
17
14
|
#{ name.first } =
|
18
15
|
if opts.key?(:#{ name.first })
|
@@ -34,29 +31,18 @@ module NamedArgs
|
|
34
31
|
end
|
35
32
|
|
36
33
|
self.module_eval <<-RUBY_EVAL, __FILE__, __LINE__
|
37
|
-
def __new_#{
|
34
|
+
def __new_#{ meth } *args, &block
|
38
35
|
opts = args.last.kind_of?( Hash ) ? args.pop : {}
|
39
36
|
#{ assigns.join("\n") }
|
40
|
-
__original_#{
|
37
|
+
__original_#{ meth } #{ names.collect{ |n| n.first }.join(', ') }, &block
|
41
38
|
end
|
42
39
|
|
43
|
-
alias __original_#{
|
44
|
-
alias #{
|
40
|
+
alias __original_#{ meth } #{ meth }
|
41
|
+
alias #{ meth } __new_#{ meth }
|
45
42
|
RUBY_EVAL
|
46
43
|
end
|
47
44
|
end
|
48
45
|
alias :named_args_for :named_arguments_for
|
46
|
+
alias :named_args :named_arguments_for
|
49
47
|
|
50
48
|
end
|
51
|
-
|
52
|
-
# for some reason in 1.9 module doesn't take methods from class...at least not like 1.8 did
|
53
|
-
# so we have to mix them into both
|
54
|
-
class Class
|
55
|
-
include NamedArgs
|
56
|
-
end
|
57
|
-
|
58
|
-
class Module
|
59
|
-
include NamedArgs
|
60
|
-
end
|
61
|
-
|
62
|
-
|
data/lib/arguments/mri.rb
CHANGED
@@ -7,15 +7,13 @@ require 'ruby2ruby'
|
|
7
7
|
|
8
8
|
module Arguments
|
9
9
|
def self.names klass, method
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
return nil
|
14
|
-
end
|
10
|
+
args = ParseTree.translate( klass, method ).assoc(:scope).assoc(:block).assoc(:args)
|
11
|
+
args = args[1..-1]
|
12
|
+
return [] if args.empty?
|
15
13
|
if args.last.instance_of? Array
|
16
14
|
vals = args.pop[1..-1]
|
17
15
|
else
|
18
|
-
# if it has no optionals
|
16
|
+
# if it has no optionals then vals is empty
|
19
17
|
vals = []
|
20
18
|
end
|
21
19
|
|
data/lib/arguments/vm.rb
CHANGED
@@ -2,7 +2,10 @@
|
|
2
2
|
module Arguments
|
3
3
|
def self.names klass, method
|
4
4
|
source, line = klass.instance_method( method ).source_location
|
5
|
-
|
5
|
+
return [] unless source and line
|
6
|
+
str = IO.readlines(source)[ line - 1 ]
|
7
|
+
return [] if str.match(/\*\w+/)
|
8
|
+
str.match(/def\s*\w+\s*\(?\s*([^)\n]*)/)[1] #This could look better
|
6
9
|
.scan(/(\w+)(?:\s*=\s*([^,]+))|(\w+)/).map{ |e| e.compact }
|
7
10
|
end
|
8
11
|
end
|
data/lib/arguments.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
$:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
2
2
|
|
3
3
|
require 'arguments/class'
|
4
|
+
|
5
|
+
|
6
|
+
|
4
7
|
RUBY_VERSION.to_f >= 1.9 ? require( 'arguments/vm' ) : require( 'arguments/mri' )
|
5
8
|
|
6
9
|
module Arguments
|
7
|
-
VERSION = '0.4.
|
10
|
+
VERSION = '0.4.7'
|
8
11
|
end
|
data/spec/arguments_spec.rb
CHANGED
@@ -67,6 +67,39 @@ describe Arguments do
|
|
67
67
|
Klass.asr(0, 1, 2, :curve => 3).should == [0,1,2,3]
|
68
68
|
end
|
69
69
|
|
70
|
+
it "should not patch methods that accept no args" do
|
71
|
+
# Arguments.should_not_receive(:names)
|
72
|
+
Klass.send( :named_arguments_for, :no_args )
|
73
|
+
lambda { @instance.no_args(1) }.should raise_error(ArgumentError)
|
74
|
+
@instance.no_args.should be_nil
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should not patch methods that use splatter op" do
|
78
|
+
Klass.send( :named_arguments_for, :splatted )
|
79
|
+
@instance.splatted(1, :args => 1).should == [1, {:args => 1}]
|
80
|
+
|
81
|
+
Klass.send( :named_arguments_for, :splatted2 )
|
82
|
+
@instance.splatted2(:a => 1, :"*args" => 3).should == []
|
83
|
+
|
84
|
+
Klass.send( :named_arguments_for, :splatted3 )
|
85
|
+
@instance.splatted3(:a => 1, :"*args" => 3).should == []
|
86
|
+
@instance.splatted3(1, :b => 2, :args => 1).should == [{:b => 2, :args => 1}]
|
87
|
+
|
88
|
+
Klass.send( :named_arguments_for, :splatted4 )
|
89
|
+
@instance.splatted4(1, :b => 2, :args => 1).should == []
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should patch methods with no optionals" do
|
94
|
+
Klass.send( :named_arguments_for, :no_opts )
|
95
|
+
lambda { @instance.no_opts(1,2, :a => 1)}.should raise_error(ArgumentError)
|
96
|
+
@instance.no_opts(1,2, :c => 1).should == 1
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should patch all methods" do
|
100
|
+
Klass.send( :named_args )
|
101
|
+
end
|
102
|
+
|
70
103
|
it "should benchmark without hack" do
|
71
104
|
puts Benchmark.measure {
|
72
105
|
1_000.times do
|
@@ -79,10 +112,6 @@ describe Arguments do
|
|
79
112
|
lambda { module TestMod; def go(a); end; named_arguments_for :go; end }
|
80
113
|
end
|
81
114
|
|
82
|
-
it "should raise if you try to call it on a c (binary) method" do
|
83
|
-
lambda { class String; named_arguments_for(:strip); end }.should raise_error( BinaryMethodError )
|
84
|
-
end
|
85
|
-
|
86
115
|
it "should benchmark with hack" do
|
87
116
|
puts Benchmark.measure {
|
88
117
|
Klass.send( :named_arguments_for, :with_block )
|
data/spec/klass.rb
CHANGED
@@ -20,11 +20,34 @@ class Klass
|
|
20
20
|
[attackTime, sustainLevel, releaseTime, curve]
|
21
21
|
end
|
22
22
|
|
23
|
+
def no_args
|
24
|
+
end
|
25
|
+
|
26
|
+
def splatted *args
|
27
|
+
args
|
28
|
+
end
|
29
|
+
|
30
|
+
def splatted2 a=1, *args
|
31
|
+
args
|
32
|
+
end
|
33
|
+
|
34
|
+
def splatted3 a, *args
|
35
|
+
args
|
36
|
+
end
|
37
|
+
|
38
|
+
def splatted4 a, b=1, *args
|
39
|
+
args
|
40
|
+
end
|
41
|
+
|
42
|
+
def no_opts a, b, c
|
43
|
+
c
|
44
|
+
end
|
45
|
+
|
23
46
|
class << self
|
24
47
|
def asr attackTime = 3, sustainLevel = 2, releaseTime = 1, curve = 0
|
25
48
|
[attackTime, sustainLevel, releaseTime, curve]
|
26
49
|
end
|
27
|
-
|
50
|
+
named_arguments_for :asr
|
28
51
|
end
|
29
52
|
|
30
53
|
def == other
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rogerdpack-arguments
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.7.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Macario Ortega
|
@@ -86,6 +86,7 @@ files:
|
|
86
86
|
- spec/klass.rb
|
87
87
|
has_rdoc: true
|
88
88
|
homepage:
|
89
|
+
licenses:
|
89
90
|
post_install_message:
|
90
91
|
rdoc_options:
|
91
92
|
- --main
|
@@ -107,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
107
108
|
requirements: []
|
108
109
|
|
109
110
|
rubyforge_project: arguments
|
110
|
-
rubygems_version: 1.
|
111
|
+
rubygems_version: 1.3.5
|
111
112
|
signing_key:
|
112
113
|
specification_version: 2
|
113
114
|
summary: You don't have to wait until Ruby 2.0 to get (named|keyword) arguments support
|