2008年4月25日

[ruby-list:44859] Re: Method#arity

From: "ARAI Shunichi" <arai@xxxxx>
Subject: [ruby-list:44858] Method#arity
Date: Fri, 25 Apr 2008 16:31:01 +0900

るびきちです。

> メソッドの引数の数を知りたいのですが、
> Method#arity以外に手段はありますか?

>
> *必須引数の数、
> *デフォルト値付き引数の数、
> *可変個引数があるかどうか、
> をそれぞれ知りたいのですが。

set_trace_funcを使う必要があるのでかなり複雑です。
rcodetoolsに含まれている rct-meth-args コマンドがメソッドの引数を表示してくれます。
$ sudo gem install rcodetools

たとえばこんなスクリプトを rct-meth-args にかけると、

# method_args_data.rb
class FixedArgsMethods
def self.singleton(a1) end
def initialize(arg) end
def f(a1) end
def b(a1,&block) end
define_method(:defmethod) {|a1|}
attr_accessor :by_attr_accessor
attr :by_attr_false
attr :by_attr_true, true
attr_reader :by_attr_reader_1, :by_attr_reader_2
attr_writer :by_attr_writer
def private_meth(x) end
private :private_meth
class << self
attr_accessor :singleton_attr_accessor
define_method(:singleton_defmethod){|a2|}
end
end

module VariableArgsMethods
def s(a1,*splat) end
def sb(a1,*splat, &block) end
def d(a1,default=nil) end
def ds(a1,default=nil,*splat) end
def dsb(a1,default=nil,*splat,&block) end
def db(a1,default=nil,&block) end
end

class Fixnum
def method_in_Fixnum(arg1, arg2) end
def self.singleton_method_in_Fixnum(arg1, arg2) end
end
class Bignum
def method_in_Bignum(arg1, arg2) end
end
class Float
def method_in_Float(arg1, arg2) end
end
class Symbol
def method_in_Symbol(arg1, arg2) end
end
class Binding
def method_in_Binding(arg1, arg2) end
end
class UnboundMethod
def method_in_UnboundMethod(arg1, arg2) end
end
class Method
def method_in_Method(arg1, arg2) end
end
class Proc
def method_in_Proc(arg1, arg2) end
end
class Continuation
def method_in_Continuation(arg1, arg2) end
end
class Thread
def method_in_Thread(arg1, arg2) end
end
# FIXME mysterious
# class FalseClass
# def method_in_FalseClass(arg1, arg2) end
# end
class TrueClass
def method_in_TrueClass(arg1, arg2) end
end
class NilClass
def method_in_NilClass(arg1, arg2) end
end
class Struct
def method_in_Struct(arg1, arg2) end
end

require 'digest'
class Digest::Base
def method_in_Digest_Base(arg1, arg2) end
end

class AnAbstractClass
$__method_args_off = true
def self.allocate
raise NotImplementedError, "#{self} is an abstract class."
end
$__method_args_off = false

def method_in_AnAbstractClass(arg1, arg2)
end

end

class AClass
include VariableArgsMethods
extend VariableArgsMethods
end

class ASubClass < AClass
end

StructA = Struct.new :a, :b
class SubclassOfStructA < StructA
attr :method_in_b
end
class StructSubclass < Struct.new(:c)
attr :method_in_c
end


こうなります。


$ rct-meth-args method_args_data.rb
FixedArgsMethods.singleton (a1)
FixedArgsMethods#initialize (arg)
FixedArgsMethods#f (a1)
FixedArgsMethods#b (a1, &block)
FixedArgsMethods#defmethod (...)
FixedArgsMethods#by_attr_accessor
FixedArgsMethods#by_attr_accessor= (value)
FixedArgsMethods#by_attr_false
FixedArgsMethods#by_attr_true
FixedArgsMethods#by_attr_true= (value)
FixedArgsMethods#by_attr_reader_1
FixedArgsMethods#by_attr_reader_2
FixedArgsMethods#by_attr_writer= (value)
FixedArgsMethods#private_meth (x)
FixedArgsMethods.singleton_attr_accessor
FixedArgsMethods.singleton_attr_accessor= (value)
FixedArgsMethods.singleton_defmethod (...)
VariableArgsMethods#s (a1, *splat)
VariableArgsMethods#sb (a1, *splat, &block)
VariableArgsMethods#d (a1, default = nil)
VariableArgsMethods#ds (a1, default = nil, *splat)
VariableArgsMethods#dsb (a1, default = nil, *splat, &block)
VariableArgsMethods#db (a1, default = nil, &block)
Fixnum#method_in_Fixnum (arg1, arg2)
Fixnum.singleton_method_in_Fixnum (arg1, arg2)
Bignum#method_in_Bignum (arg1, arg2)
Float#method_in_Float (arg1, arg2)
Symbol#method_in_Symbol (arg1, arg2)
Binding#method_in_Binding (arg1, arg2)
UnboundMethod#method_in_UnboundMethod (arg1, arg2)
Method#method_in_Method (arg1, arg2)
Proc#method_in_Proc (arg1, arg2)
Continuation#method_in_Continuation (arg1, arg2)
Thread#method_in_Thread (arg1, arg2)
TrueClass#method_in_TrueClass (arg1, arg2)
NilClass#method_in_NilClass (arg1, arg2)
Struct#method_in_Struct (arg1, arg2)
Digest::Instance#update (...)
Digest::Instance#<< (...)
Digest::Instance#reset (...)
Digest::Instance#digest_length (...)
Digest::Instance#block_length (...)
Digest::Instance#== (...)
Digest::Instance#inspect (...)
Digest::Instance#new (...)
Digest::Instance#digest (...)
Digest::Instance#digest! (...)
Digest::Instance#hexdigest (...)
Digest::Instance#hexdigest! (...)
Digest::Instance#to_s (...)
Digest::Instance#length (...)
Digest::Instance#size (...)
Digest::Class.digest (...)
Digest::Class.hexdigest (...)
Digest::Base#reset (...)
Digest::Base#update (...)
Digest::Base#<< (...)
Digest::Base#finish (...)
Digest::Base#digest_length (...)
Digest::Base#block_length (...)
Digest::Class.file (name)
Digest::Instance#file (name)
Digest::Base#method_in_Digest_Base (...)
AnAbstractClass#method_in_AnAbstractClass (...)
include AClass <= VariableArgsMethods
extend AClass <- VariableArgsMethods
class ASubClass < AClass
class <Struct: a,b> < Struct
class SubclassOfStructA < StructA
SubclassOfStructA#method_in_b
class <Struct: c> < Struct
class StructSubclass < <Struct: c>
StructSubclass#method_in_c


参考になれば幸いです。

--
rubikitch
Blog: http://d.hatena.ne.jp/rubikitch/
Site: http://www.rubyist.net/~rubikitch/

投稿者 xml-rpc : 2008年4月25日 18:53
役に立ちました?:
過去のフィードバック 平均:(0) 総合:(0) 投票回数:(0)
本記事へのTrackback: http://hoop.euqset.org/blog/mt-tb2006.cgi/72560
トラックバック
コメント
コメントする




画像の中に見える文字を入力してください。