method-args 0.0.1

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/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ pkg
2
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source :gemcutter
2
+
3
+ # Specify your gem's dependencies in optitron.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,35 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ method_args (0.0.1)
5
+ ruby2ruby (~> 1.2.4)
6
+ ruby_parser (~> 2.0)
7
+ sexp_processor (~> 3.0.4)
8
+
9
+ GEM
10
+ remote: http://rubygems.org/
11
+ specs:
12
+ callsite (0.0.4)
13
+ minitest (2.0.2)
14
+ phocus (1.1)
15
+ rake (0.8.7)
16
+ ruby2ruby (1.2.5)
17
+ ruby_parser (~> 2.0)
18
+ sexp_processor (~> 3.0)
19
+ ruby_parser (2.0.5)
20
+ sexp_processor (~> 3.0)
21
+ sexp_processor (3.0.5)
22
+
23
+ PLATFORMS
24
+ ruby
25
+
26
+ DEPENDENCIES
27
+ bundler (~> 1.0.0)
28
+ callsite (~> 0.0.4)
29
+ method_args!
30
+ minitest
31
+ phocus
32
+ rake
33
+ ruby2ruby (~> 1.2.4)
34
+ ruby_parser (~> 2.0)
35
+ sexp_processor (~> 3.0.4)
data/README.markdown ADDED
@@ -0,0 +1,40 @@
1
+ # MethodArgs
2
+
3
+ ## Purpose
4
+
5
+ You've got a method, but want to know more about the arguments? `#arity` and `#parameters` (if available) are useful,
6
+ but not nearly enough. You need something better. Like, the default arguments. *MethodArgs* makes this simple. It operates
7
+ on a source file to supply the more details argument information by parsing the code itself.
8
+
9
+ ## Usage
10
+
11
+ Pretend you have a file `your_ruby_file.rb`:
12
+
13
+ class MyClass
14
+ def initialize
15
+ @default_value = 'hello'
16
+ end
17
+
18
+ def something(one, two = 'two', three = @default_value)
19
+ end
20
+ end
21
+
22
+ To look at the arguments to something, do the following.
23
+
24
+ MethodArgs.load('your_ruby_file') # <-- this also requires the file
25
+ MyClass.arg_list(:something)
26
+
27
+ This will return an `ArgList` object. You can then look at the names & types.
28
+
29
+ MyClass.arg_list(:something).names
30
+ # => [:one, :two, :three]
31
+
32
+ MyClass.arg_list(:something).types
33
+ # => [:required, :optional, :splat]
34
+
35
+ If you want to get the value of a default argument, you'll need a context in which to evaluate it, namely,
36
+ an instance of the class from which the method derives.
37
+
38
+ obj = MyClass.new
39
+ MyClass.arg_list(:something).last.default_value(obj)
40
+ # => 'hello'
data/Rakefile ADDED
@@ -0,0 +1,20 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+
4
+ desc "Run tests"
5
+ task :test do
6
+ $: << 'lib'
7
+ require 'method_args'
8
+ require 'test/helper'
9
+ Dir['test/**/test_*.rb'].each { |test| require test }
10
+ end
11
+
12
+ require 'rake/rdoctask'
13
+ desc "Generate documentation"
14
+ Rake::RDocTask.new do |rd|
15
+ rd.main = "README.rdoc"
16
+ rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
17
+ rd.rdoc_dir = 'rdoc'
18
+ end
19
+
20
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,170 @@
1
+ require 'ruby2ruby'
2
+ require 'ruby_parser'
3
+ require 'sexp_processor'
4
+
5
+ module MethodArgs
6
+
7
+ class ArgList < Array
8
+ class Arg
9
+
10
+ attr_reader :name, :type
11
+
12
+ def initialize(cls, arg)
13
+ @cls = cls
14
+ @name = arg[0]
15
+ @type = arg[1]
16
+ @default = arg[2]
17
+ end
18
+
19
+ def required?
20
+ @type == :required
21
+ end
22
+
23
+ def optional?
24
+ @type == :optional
25
+ end
26
+
27
+ def splat?
28
+ @type == :splat
29
+ end
30
+
31
+ def default_value(inst)
32
+ return nil if @default.nil?
33
+ raise "You must evaluate defaults in the context of a matching class. #{inst.class.name} is not a #{@cls.name}." unless inst.is_a?(@cls)
34
+ inst.instance_eval(@default)
35
+ end
36
+ end
37
+
38
+ def required_size
39
+ inject(0) {|count, arg| count += arg.required? ? 1 : 0}
40
+ end
41
+ alias_method :required_count, :required_size
42
+
43
+ def names
44
+ map(&:name)
45
+ end
46
+
47
+ def types
48
+ map(&:type)
49
+ end
50
+
51
+ def initialize(cls, method)
52
+ @cls, @method = cls, method
53
+ end
54
+
55
+ def to_method
56
+ @cls.instance_method(@method)
57
+ end
58
+ end
59
+
60
+
61
+ def self.load(file)
62
+ file = File.expand_path(file)
63
+ require file
64
+ parser = RubyParser.new
65
+ sexp = parser.process(File.read(File.exist?(file) ? file : "#{file}.rb"))
66
+ method_args = Processor.new
67
+ method_args.process(sexp)
68
+ end
69
+
70
+ class Processor < SexpProcessor
71
+
72
+ attr_reader :method_maps
73
+
74
+ def initialize
75
+ @method_maps = Hash.new{|h,k| h[k] = {}}
76
+ @current_class = []
77
+ super()
78
+ end
79
+
80
+ def process_module(exp)
81
+ exp.shift
82
+ @current_class << exp.first.to_sym
83
+ process(exp)
84
+ @current_class.pop
85
+ exp.clear
86
+ exp
87
+ end
88
+
89
+ def process_class(exp)
90
+ exp.shift
91
+ current_class_size = @current_class.size
92
+ case exp.first
93
+ when Symbol
94
+ @current_class << exp.first.to_sym
95
+ process(exp)
96
+ else
97
+ if exp.first.first == :colon2
98
+ exp.first.shift
99
+ class_exp = exp.shift
100
+ class_exp[0, class_exp.size - 1].each do |const|
101
+ @current_class << const.last
102
+ end
103
+ @current_class << class_exp.last
104
+ else
105
+ raise
106
+ end
107
+ exp.shift
108
+ process(exp.first)
109
+ end
110
+ @current_class.slice!(current_class_size, @current_class.size)
111
+ exp.clear
112
+ exp
113
+ end
114
+
115
+ def process_defn(exp)
116
+ exp.shift
117
+ @current_method = exp.shift
118
+ @ruby2ruby = Ruby2Ruby.new
119
+ process_args(exp.shift)
120
+ scope = exp.shift
121
+ exp
122
+ end
123
+
124
+ def process_args(exp)
125
+ exp.shift
126
+ arg_list = ArgList.new(current_class, @current_method)
127
+ while !exp.empty?
128
+ t = exp.shift
129
+ case t
130
+ when Symbol
131
+ arg_list << if t.to_s[0] == ?*
132
+ ArgList::Arg.new(current_class, [t.to_s[1, t.to_s.size].to_sym, :splat])
133
+ else
134
+ ArgList::Arg.new(current_class, [t, :required])
135
+ end
136
+ when Sexp
137
+ case t.shift
138
+ when :block
139
+ lasgn = t.shift
140
+ lasgn.shift
141
+ name = lasgn.shift
142
+ new_arg = ArgList::Arg.new(current_class, [name, :optional, @ruby2ruby.process(lasgn.last)])
143
+ arg_list.each_with_index{|arg, idx| arg_list[idx] = new_arg if arg.name == name}
144
+ end
145
+ end
146
+ end
147
+ @method_maps[current_classname][@current_method] = arg_list
148
+ add_methods
149
+ end
150
+
151
+ def add_methods
152
+ unless current_class.const_defined?(:ArgList)
153
+ current_class.send(:const_set, :ArgList, @method_maps[current_classname])
154
+ current_class.module_eval "
155
+ def self.arg_list(method_name)
156
+ ArgList[method_name]
157
+ end
158
+ "
159
+ end
160
+ end
161
+
162
+ def current_classname
163
+ @current_class.map{|c| c.to_s}.join('::')
164
+ end
165
+
166
+ def current_class
167
+ @current_class.inject(Module) {|c, m| c.const_get(m)}
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,3 @@
1
+ module MethodArgs
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "method_args/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "method-args"
7
+ s.version = MethodArgs::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Joshua Hull"]
10
+ s.email = ["joshbuddy@gmail.com"]
11
+ s.homepage = "https://github.com/joshbuddy/method_args"
12
+ s.summary = "Get back more detailed information about the arguments for a method"
13
+ s.description = "Get back more detailed information about the arguments for a method"
14
+
15
+ s.rubyforge_project = "method_args2"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_dependency "ruby_parser", "~> 2.0"
23
+ s.add_dependency "ruby2ruby", "~> 1.2.4"
24
+ s.add_dependency "sexp_processor", "~> 3.0.4"
25
+ s.add_development_dependency "callsite", "~> 0.0.4"
26
+ s.add_development_dependency "bundler", "~> 1.0.0"
27
+ s.add_development_dependency "rake"
28
+ s.add_development_dependency "phocus"
29
+ s.add_development_dependency "minitest"
30
+ end
@@ -0,0 +1,21 @@
1
+ class One
2
+ attr_accessor :two_method
3
+
4
+ def no_args
5
+ end
6
+
7
+ def one_args(one)
8
+ end
9
+
10
+ def two_args(one, two)
11
+ end
12
+
13
+ def splat_args(one, two, *three)
14
+ end
15
+
16
+ def default_args(one, two = 'two')
17
+ end
18
+
19
+ def default_args_with_dependant_value(one, two = two_method)
20
+ end
21
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'minitest/autorun'
2
+ require 'phocus'
3
+ require 'callsite'
4
+ Callsite.activate_string_methods
@@ -0,0 +1,37 @@
1
+ class TestMethodArgs < MiniTest::Unit::TestCase
2
+ def setup
3
+ MethodArgs.load(~'fixtures/1')
4
+ end
5
+
6
+ def test_arg_counts
7
+ assert_equal 0, One.arg_list(:no_args).count
8
+ assert_equal 1, One.arg_list(:one_args).count
9
+ assert_equal 2, One.arg_list(:two_args).count
10
+ assert_equal 3, One.arg_list(:splat_args).count
11
+ assert_equal 2, One.arg_list(:splat_args).required_count
12
+ assert_equal 2, One.arg_list(:default_args).count
13
+ assert_equal 1, One.arg_list(:default_args).required_count
14
+ assert_equal 2, One.arg_list(:default_args_with_dependant_value).count
15
+ assert_equal 1, One.arg_list(:default_args_with_dependant_value).required_count
16
+ end
17
+
18
+ def test_arg_types
19
+ assert_equal [], One.arg_list(:no_args).types
20
+ assert_equal [:required], One.arg_list(:one_args).types
21
+ assert_equal [:required, :required], One.arg_list(:two_args).types
22
+ assert_equal [:required, :required, :splat], One.arg_list(:splat_args).types
23
+ assert_equal [:required, :optional], One.arg_list(:default_args).types
24
+ assert_equal [:required, :optional], One.arg_list(:default_args_with_dependant_value).types
25
+ end
26
+
27
+ def test_arg_method
28
+ assert_equal One.instance_method(:no_args), One.arg_list(:no_args).to_method
29
+ end
30
+
31
+ def test_default_args
32
+ one = One.new
33
+ one.two_method = 'happy times'
34
+ assert_equal 'happy times', One.arg_list(:default_args_with_dependant_value).last.default_value(one)
35
+ end
36
+
37
+ end
metadata ADDED
@@ -0,0 +1,200 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: method-args
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Joshua Hull
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-01-02 00:00:00 -08:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: ruby_parser
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 2
32
+ - 0
33
+ version: "2.0"
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: ruby2ruby
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ hash: 23
45
+ segments:
46
+ - 1
47
+ - 2
48
+ - 4
49
+ version: 1.2.4
50
+ type: :runtime
51
+ version_requirements: *id002
52
+ - !ruby/object:Gem::Dependency
53
+ name: sexp_processor
54
+ prerelease: false
55
+ requirement: &id003 !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ~>
59
+ - !ruby/object:Gem::Version
60
+ hash: 15
61
+ segments:
62
+ - 3
63
+ - 0
64
+ - 4
65
+ version: 3.0.4
66
+ type: :runtime
67
+ version_requirements: *id003
68
+ - !ruby/object:Gem::Dependency
69
+ name: callsite
70
+ prerelease: false
71
+ requirement: &id004 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ hash: 23
77
+ segments:
78
+ - 0
79
+ - 0
80
+ - 4
81
+ version: 0.0.4
82
+ type: :development
83
+ version_requirements: *id004
84
+ - !ruby/object:Gem::Dependency
85
+ name: bundler
86
+ prerelease: false
87
+ requirement: &id005 !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ~>
91
+ - !ruby/object:Gem::Version
92
+ hash: 23
93
+ segments:
94
+ - 1
95
+ - 0
96
+ - 0
97
+ version: 1.0.0
98
+ type: :development
99
+ version_requirements: *id005
100
+ - !ruby/object:Gem::Dependency
101
+ name: rake
102
+ prerelease: false
103
+ requirement: &id006 !ruby/object:Gem::Requirement
104
+ none: false
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ hash: 3
109
+ segments:
110
+ - 0
111
+ version: "0"
112
+ type: :development
113
+ version_requirements: *id006
114
+ - !ruby/object:Gem::Dependency
115
+ name: phocus
116
+ prerelease: false
117
+ requirement: &id007 !ruby/object:Gem::Requirement
118
+ none: false
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ hash: 3
123
+ segments:
124
+ - 0
125
+ version: "0"
126
+ type: :development
127
+ version_requirements: *id007
128
+ - !ruby/object:Gem::Dependency
129
+ name: minitest
130
+ prerelease: false
131
+ requirement: &id008 !ruby/object:Gem::Requirement
132
+ none: false
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ hash: 3
137
+ segments:
138
+ - 0
139
+ version: "0"
140
+ type: :development
141
+ version_requirements: *id008
142
+ description: Get back more detailed information about the arguments for a method
143
+ email:
144
+ - joshbuddy@gmail.com
145
+ executables: []
146
+
147
+ extensions: []
148
+
149
+ extra_rdoc_files: []
150
+
151
+ files:
152
+ - .gitignore
153
+ - Gemfile
154
+ - Gemfile.lock
155
+ - README.markdown
156
+ - Rakefile
157
+ - lib/method_args.rb
158
+ - lib/method_args/version.rb
159
+ - method_args.gemspec
160
+ - test/fixtures/1.rb
161
+ - test/helper.rb
162
+ - test/test_method_args.rb
163
+ has_rdoc: true
164
+ homepage: https://github.com/joshbuddy/method_args
165
+ licenses: []
166
+
167
+ post_install_message:
168
+ rdoc_options: []
169
+
170
+ require_paths:
171
+ - lib
172
+ required_ruby_version: !ruby/object:Gem::Requirement
173
+ none: false
174
+ requirements:
175
+ - - ">="
176
+ - !ruby/object:Gem::Version
177
+ hash: 3
178
+ segments:
179
+ - 0
180
+ version: "0"
181
+ required_rubygems_version: !ruby/object:Gem::Requirement
182
+ none: false
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ hash: 3
187
+ segments:
188
+ - 0
189
+ version: "0"
190
+ requirements: []
191
+
192
+ rubyforge_project: method_args2
193
+ rubygems_version: 1.3.7
194
+ signing_key:
195
+ specification_version: 3
196
+ summary: Get back more detailed information about the arguments for a method
197
+ test_files:
198
+ - test/fixtures/1.rb
199
+ - test/helper.rb
200
+ - test/test_method_args.rb