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 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
- nu.meth(10, :a => -10) #=> [-10, :b, :c]
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
 
@@ -1,18 +1,15 @@
1
- # used to throw if you try to call it on a binary method
2
- class BinaryMethodError < Exception; end
3
-
4
- module NamedArgs
5
-
1
+ class Class
6
2
  def named_arguments_for *methods
7
- methods.each do |method|
8
- names = Arguments.names self, method
9
- raise BinaryMethodError.new("tried to call it on a Binary Method" + method.to_s) unless names
10
- assigns = []
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_#{ method } *args, &block
34
+ def __new_#{ meth } *args, &block
38
35
  opts = args.last.kind_of?( Hash ) ? args.pop : {}
39
36
  #{ assigns.join("\n") }
40
- __original_#{ method } #{ names.collect{ |n| n.first }.join(', ') }, &block
37
+ __original_#{ meth } #{ names.collect{ |n| n.first }.join(', ') }, &block
41
38
  end
42
39
 
43
- alias __original_#{ method } #{ method }
44
- alias #{ method } __new_#{ method }
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
- begin
11
- args = ParseTree.translate( klass, method ).assoc(:scope).assoc(:block).assoc(:args)[1..-1]
12
- rescue NoMethodError # binary method will fail on one of those assoc's
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
- IO.readlines(source)[ line - 1 ].match(/def\s*\w+\s*\(?\s*([^)\n]*)/)[1] #This could look better
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.3'
10
+ VERSION = '0.4.7'
8
11
  end
@@ -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
- named_arguments_for :asr
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.3.3
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.2.0
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