get_args 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Clinton R. Nixon
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,30 @@
1
+ = get_args
2
+
3
+ Extracted from Merb, get_args allows you to query a method for its argument names and defaults.
4
+
5
+ This gem exists so you can get this functionality without having to include all of Merb.
6
+
7
+ == Usage
8
+
9
+ class Dummy
10
+ def one_arg(foo); end
11
+ def multiple_args(foo, bar, baz); end
12
+ def optional_args(foo, bar = 1); end
13
+ def star_args(*foo); end
14
+ end
15
+
16
+ Dummy.instance_method(:one_arg).get_args
17
+ # => [[[:foo]], []]
18
+
19
+ Dummy.instance_method(:multiple_args).get_args
20
+ # => [[[:foo], [:bar], [:baz]], []]
21
+
22
+ Dummy.instance_method(:optional_args).get_args
23
+ # => [[[:foo], [:bar, 1]], [:bar]]
24
+
25
+ Dummy.instance_method(:star_args).get_args
26
+ # => [[[%s[*foo]]], []]
27
+
28
+ == Copyright
29
+
30
+ Copyright (c) 2009 Clinton R. Nixon. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,43 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gemspec|
7
+ gemspec.name = "get_args"
8
+ gemspec.summary = "Allows one to introspect on the argument names and defaults for a method."
9
+ gemspec.description = %Q[
10
+ Extracted from Merb, get_args allows you to query a method for its argument names and defaults.
11
+
12
+ This gem exists so you can get this functionality without having to include all of Merb.
13
+ ].strip
14
+ gemspec.email = "crnixon@gmail.com"
15
+ gemspec.homepage = "http://github.com/crnixon/get_args"
16
+ gemspec.authors = ["maiha", "Yehuda Katz"]
17
+ gemspec.add_dependency('extlib', '>= 0.9.13')
18
+ end
19
+ Jeweler::GemcutterTasks.new
20
+ rescue LoadError
21
+ puts "Jeweler not available. Install it with: sudo gem install jeweler"
22
+ end
23
+
24
+ require 'rake/testtask'
25
+ Rake::TestTask.new(:test) do |test|
26
+ test.libs << 'lib' << 'test'
27
+ test.pattern = 'test/**/test_*.rb'
28
+ test.verbose = true
29
+ end
30
+
31
+ task :test => :check_dependencies
32
+
33
+ task :default => :test
34
+
35
+ require 'rake/rdoctask'
36
+ Rake::RDocTask.new do |rdoc|
37
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
38
+
39
+ rdoc.rdoc_dir = 'rdoc'
40
+ rdoc.title = "get_args #{version}"
41
+ rdoc.rdoc_files.include('README*')
42
+ rdoc.rdoc_files.include('lib/**/*.rb')
43
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
data/lib/get_args.rb ADDED
@@ -0,0 +1,20 @@
1
+ require 'extlib'
2
+
3
+ $:.push(File.dirname(__FILE__))
4
+
5
+ if RUBY_PLATFORM == "java"
6
+ require 'jruby_args'
7
+ elsif RUBY_VERSION < "1.9"
8
+ require 'mri_args'
9
+ else
10
+ require 'vm_args'
11
+ end
12
+
13
+ class UnboundMethod
14
+ include GetArgs
15
+ end
16
+
17
+ class Method
18
+ include GetArgs
19
+ end
20
+
data/lib/jruby_args.rb ADDED
@@ -0,0 +1,67 @@
1
+ require 'java'
2
+ require 'jruby'
3
+
4
+ module GetArgs
5
+ Methods = org.jruby.internal.runtime.methods
6
+
7
+ def get_args
8
+ real_method = JRuby.reference(self)
9
+
10
+ # hack to expose a protected field; could be improved in 1.1.5
11
+ method_field = org.jruby.RubyMethod.java_class.declared_field(:method)
12
+
13
+ method_field.accessible = true
14
+
15
+ dyn_method = method_field.value(real_method)
16
+
17
+ case dyn_method
18
+ when Methods.MethodArgs
19
+ return build_args(dyn_method.args_node)
20
+ else
21
+ raise "Can't get args from method: #{self}"
22
+ end
23
+ end
24
+
25
+ def build_args(args_node)
26
+ args = []
27
+ required = []
28
+ optional = []
29
+
30
+ # required args
31
+ if (args_node.args && args_node.args.size > 0)
32
+ required << args_node.args.child_nodes.map { |arg| [arg.name.to_s.intern] }
33
+ end
34
+
35
+ # optional args
36
+ if (args_node.opt_args && args_node.opt_args.size > 0)
37
+ optional << args_node.opt_args.child_nodes.map do |arg|
38
+ name = arg.name.to_s.intern
39
+ value_node = arg.value_node
40
+ case value_node
41
+ when org.jruby.ast::FixnumNode
42
+ value = value_node.value
43
+ when org.jruby.ast::SymbolNode
44
+ value = value_node.get_symbol(JRuby.runtime)
45
+ when org.jruby.ast::StrNode
46
+ value = value_node.value
47
+ else
48
+ value = nil
49
+ end
50
+ [name, value]
51
+ end
52
+ end
53
+
54
+ first_args = required.first
55
+ optional.first.each {|arg| first_args << arg} if optional.first
56
+
57
+ args = [first_args]
58
+
59
+ rest = args_node.rest_arg_node
60
+ args << (rest ? rest.name.to_s.intern : nil)
61
+
62
+ block = args_node.block_arg_node
63
+ args << (block ? block.name.to_s.intern : nil)
64
+
65
+ args
66
+ end
67
+ end
data/lib/mri_args.rb ADDED
@@ -0,0 +1,88 @@
1
+ require 'parse_tree'
2
+ require 'ruby2ruby'
3
+
4
+ class ParseTreeArray < Array
5
+ R2R = Object.const_defined?(:Ruby2Ruby) ? Ruby2Ruby : RubyToRuby
6
+
7
+ def self.translate(*args)
8
+ sexp = ParseTree.translate(*args)
9
+ # ParseTree.translate returns [nil] if called on an inherited method, so walk
10
+ # up the inheritance chain to find the class that the method was defined in
11
+ unless sexp.first
12
+ klass = args.first.ancestors.detect do |klass|
13
+ klass.public_instance_methods(false).include?(args.last.to_s)
14
+ end
15
+ sexp = ParseTree.translate(klass, args.last) if klass
16
+ end
17
+ sexp = Unifier.new.process(sexp)
18
+ self.new(sexp)
19
+ end
20
+
21
+ def deep_array_node(type = nil)
22
+ each do |node|
23
+ return ParseTreeArray.new(node) if node.is_a?(Array) && (!type || node[0] == type)
24
+ next unless node.is_a?(Array)
25
+ return ParseTreeArray.new(node).deep_array_node(type)
26
+ end
27
+ nil
28
+ end
29
+
30
+ def arg_nodes
31
+ self[1..-1].inject([]) do |sum,item|
32
+ sum << [item] unless item.is_a?(Array)
33
+ sum
34
+ end
35
+ end
36
+
37
+ def get_args
38
+ if arg_node = deep_array_node(:args)
39
+ # method defined with def keyword
40
+ args = arg_node.arg_nodes
41
+ default_node = arg_node.deep_array_node(:block)
42
+ return [args, []] unless default_node
43
+ else
44
+ # assuming method defined with Module#define_method
45
+ return [[],[]]
46
+ end
47
+
48
+ # if it was defined with def, and we found the default_node,
49
+ # that should bring us back to regularly scheduled programming..
50
+ lasgns = default_node[1..-1]
51
+ lasgns.each do |asgn|
52
+ args.assoc(asgn[1]) << eval(R2R.new.process(asgn[2]))
53
+ end
54
+ [args, (default_node[1..-1].map { |asgn| asgn[1] })]
55
+ end
56
+
57
+ end
58
+
59
+ # Used in mapping controller arguments to the params hash.
60
+ # NOTE: You must have the 'ruby2ruby' gem installed for this to work.
61
+ #
62
+ # ==== Examples
63
+ # # In PostsController
64
+ # def show(id) #=> id is the same as params[:id]
65
+ module GetArgs
66
+
67
+ # ==== Returns
68
+ # Array:: Method arguments and their default values.
69
+ #
70
+ # ==== Examples
71
+ # class Example
72
+ # def hello(one,two="two",three)
73
+ # end
74
+ #
75
+ # def goodbye
76
+ # end
77
+ # end
78
+ #
79
+ # Example.instance_method(:hello).get_args
80
+ # #=> [[:one], [:two, "two"], [:three, "three"]]
81
+ # Example.instance_method(:goodbye).get_args #=> nil
82
+ def get_args
83
+ klass, meth = self.to_s.split(/ /).to_a[1][0..-2].split("#")
84
+ # Remove stupidity for #<Method: Class(Object)#foo>
85
+ klass = $` if klass =~ /\(/
86
+ ParseTreeArray.translate(Object.full_const_get(klass), meth).get_args
87
+ end
88
+ end
data/lib/vm_args.rb ADDED
@@ -0,0 +1,27 @@
1
+ begin
2
+ require "methopara"
3
+ rescue
4
+ puts "Make sure you have methopara http://github.com/genki/methopara installed if you want to use action args on Ruby 1.9"
5
+ end
6
+
7
+ module GetArgs
8
+ def get_args
9
+ unless respond_to?(:parameters)
10
+ raise NotImplementedError, "Ruby #{RUBY_VERSION} doesn't support #{self.class}#parameters"
11
+ end
12
+
13
+ required = []
14
+ optional = []
15
+
16
+ parameters.each do |(type, name)|
17
+ if type == :opt
18
+ required << [name, nil]
19
+ optional << name
20
+ else
21
+ required << [name]
22
+ end
23
+ end
24
+
25
+ return [required, optional]
26
+ end
27
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ require 'get_args'
7
+
8
+ class Test::Unit::TestCase
9
+ end
@@ -0,0 +1,17 @@
1
+ require 'helper'
2
+
3
+ class Dummy
4
+ def one_arg(foo); end
5
+ def multiple_args(foo, bar, baz); end
6
+ def optional_args(foo, bar = 1); end
7
+ def star_args(*foo); end
8
+ end
9
+
10
+ class TestGetArgs < Test::Unit::TestCase
11
+ def test_get_args
12
+ assert_equal [[[:foo]], []], Dummy.instance_method(:one_arg).get_args
13
+ assert_equal [[[:foo], [:bar], [:baz]], []], Dummy.instance_method(:multiple_args).get_args
14
+ assert_equal [[[:foo], [:bar, 1]], [:bar]], Dummy.instance_method(:optional_args).get_args
15
+ assert_equal [[[%s[*foo]]], []], Dummy.instance_method(:star_args).get_args
16
+ end
17
+ end
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: get_args
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - maiha
8
+ - Yehuda Katz
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-12-11 00:00:00 -05:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: extlib
18
+ type: :runtime
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: 0.9.13
25
+ version:
26
+ description: |-
27
+ Extracted from Merb, get_args allows you to query a method for its argument names and defaults.
28
+
29
+ This gem exists so you can get this functionality without having to include all of Merb.
30
+ email: crnixon@gmail.com
31
+ executables: []
32
+
33
+ extensions: []
34
+
35
+ extra_rdoc_files:
36
+ - LICENSE
37
+ - README.rdoc
38
+ files:
39
+ - .document
40
+ - .gitignore
41
+ - LICENSE
42
+ - README.rdoc
43
+ - Rakefile
44
+ - VERSION
45
+ - lib/get_args.rb
46
+ - lib/jruby_args.rb
47
+ - lib/mri_args.rb
48
+ - lib/vm_args.rb
49
+ - test/helper.rb
50
+ - test/test_get_args.rb
51
+ has_rdoc: true
52
+ homepage: http://github.com/crnixon/get_args
53
+ licenses: []
54
+
55
+ post_install_message:
56
+ rdoc_options:
57
+ - --charset=UTF-8
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: "0"
65
+ version:
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: "0"
71
+ version:
72
+ requirements: []
73
+
74
+ rubyforge_project:
75
+ rubygems_version: 1.3.5
76
+ signing_key:
77
+ specification_version: 3
78
+ summary: Allows one to introspect on the argument names and defaults for a method.
79
+ test_files:
80
+ - test/helper.rb
81
+ - test/test_get_args.rb