[ruby-list:2052] Methods.htm 作成 tool
From:
(Dezawa Shin-ichiro) <dezawa@...>
Date:
1997-02-04 14:23:47 UTC
List:
ruby-list #2052
出沢です
「module の関数も取り込み出したんで、private も取り扱う用に
なったんですね」、っていわれてはて、、、と思ってたんですが、
みてみたら rb_define_module_function でした。
たしか 組み込み class にincludeされている enum と compare
には 無かった定義だと調べた気はするが、、、
わすれた。
----Next_Part(Tue_Feb__4_23:18:17_1997)--
Content-Type: Text/Plain; charset=iso-2022-jp
Content-Transfer-Encoding: 7bit
#!/usr/local/bin/ruby
# メソッドの ovwerideがあったとき、すべての super の LIST を作る
# クラス名 は 最後に定義したもの。 link はマニュアルにあるものに張る。
# cArray = rb_define_class("Array", cObject);
# rb_include_module(cArray, mEnumerable);
#
# rb_define_singleton_method(cArray, "new", ary_s_new, -1);
# rb_define_singleton_method(cArray, "[]", ary_s_create, -1);
# rb_define_method(cArray, "to_s", ary_to_s, 0);
# rb_define_method(cArray, "inspect", ary_inspect, 0);
require "getopts"
getopts( "i" ) # Index
# grobals
$ManDir="/usr/man/html/ruby-man/man/" # dir of *.html
$Anker = Hash.new # anker-list from $ManDir/*.html
# key = method name(String) "plus", "class.grob" ,,
# value= [ [class-name,anker], [ ], [ ],,,]
$CLASS=Hash.new # classID => object of CLS
# print format
$tail=["%s</TD><TD> | </TD>","%s</TD></TR>\n"]
$format0="<TD>%s%s</A></TD><TD>"
$format1="<TD>%s</TD><TD>"
$RenamMethod={ # method name rewrite rule
"%" =>"mod", "&" =>"and", "<" =>"gt", "<=" =>"ge", "<<" =>"lshift",
"**"=>"pow", "|" =>"or", ">" =>"lt", ">=" =>"le", ">>"=>"rshift",
"/" =>"div", "^" =>"xor", "==" =>"equal","<=>"=>"cmp", "[]" =>"aref",
"+" =>"plus", "~" =>"inv", "==="=>"eqq", "=~" =>"match","[]="=>"aset",
"-" =>"minus","+@"=>"uplus","-@" =>"uminus",
"*" =>"mul", "times" =>"mul"
}
def rename(methodName)
# Rename special method
href = methodName.dup
href = $RenamMethod[href] if $RenamMethod[href]
href.sub(/\?$/,"_p").sub(/!$/,"_bang")
end
################# class define ######
class CLS
# propaty
# @classtype(Str) "class", "module", "boot", or nil
# @name(Str) @super(Str or nil)
# @modules(Ary) classID of included module
# @method(Hash) Key:method-name(Str) Value:class-name(Str)
# @classmethod(Hash) same as @method. Key:method-name without class-name
# @methods
# @classmethods(Hash)
# all methods from methoclass, module, super, super-super
# Key:method-name(Str) Value: Array of class-name(Str)
# @supers(Ary) Array of classID as [super, super-super,super-super,,,,]
#
def setclass(name,superClass=nil,classtype=nil)
@name=name ; @super = superClass ; @classtype = classtype
end
def classtype
@classtype
end
def name
@name
end
def setModule(incModule)
if @modules
@modules.push(incModule)
else
@modules=Array[incModule]
end
end
def modules
@modules
end
def setMethod(method)
# allMethod により、子供に取り込まれるため、どのクラスからの
# method かを明確にするため、値として クラス名(Str)を持たせる
if @method
@method[method]=[@name]
else
@method={method=>[@name]}
end
end
def setClassMethod(method)
if @classmethod
@classmethod[method]=[@name]
else
@classmethod={method=>[@name]}
end
end
def getMethod
@method
end
def addHash(a,b)
if a
c = a.dup
if b
b.each{|k,v|
if c[k] == nil
c[k]=v
else
c[k]+= v
end
}
end
end
c
end
def allClassMethod
unless @classmethods
if @classmethod
@classmethods=@classmethod.dup
else
@classmethods=Hash.new
end
end
if $CLASS[@super]
@classmethods=addHash(@classmethods,$CLASS[@super].allClassMethod)
end
@classmethods
end
def allMethod
unless @methods
if @method
@methods=@method.dup
else
@methods=Hash.new
end
if @modules && @modules.size > 0
@modules.each{ |modul|
if $CLASS[modul]
@methods=addHash(@methods, $CLASS[modul].allMethod)
end
}
end
if $CLASS[@super]
@methods=addHash(@methods,$CLASS[@super].allMethod)
end
end
@methods
end
def allSuper
unless @supers # @super is classID, @supers is Array of String
@supers=Array.new
if $CLASS[@super]
@supers << [$CLASS[@super].name]
@supers += $CLASS[@super].allSuper
end
end
@supers
end
########### print out method ##########
def printHREFforClass
if allSuper.size>0
@supersList = " < " + @supers.join(" < ")
else
@supersList = ""
end
printf("<TR> <TD><A HREF=\"#%s\">%s</A></TD><TD>%s</TD></TR>\n",
@name,@name,@supersList)
end
def printClassHeader
printf("<p><A NAME=\"%s\"></A><A href=\"%s.html\"><font size=3>%s</font></A>%s<br>\n<TABLE BORDER=0>\n",
@name,@name,@name,@supersList)
end
def printClassMethod
allClassMethod # @classmethods(Hash) made
if @classmethods.size>0
@right=0 # 0: left column, 1: right column
print "<TR> <TD>クラスメソッド</TD></TR>\n"
@classmethods.keys.sort.each{|methodName|
printMethodHref(methodName,@classmethods[methodName])
}
end
end
def printMethod
allMethod # @methods(Hash) made
if @methods.size>0
@right=0 # 0: left column, 1: right column
print "<TR> <TD>メソッド</TD></TR>\n"
@methods.keys.sort.each{|methodName|
printMethodHref(methodName,@methods[methodName])
}
end
end
def rename(methodName)
# Rename special method
href = methodName.dup
href = $RenamMethod[href] if $RenamMethod[href]
href.sub(/\?$/,"_p").sub(/!$/,"_bang")
end
def printMethodHref(methodName,classNameAry)
# classNameAry is この メソッドが定義されてるクラスの Array
href=rename(methodName) # example
# methodName "+", "sub", "class.grob"
# --> href "plus","sub", "class.grob"
method = methodName.dup
method.sub!(/class\./,"")
hrefClass = nil
#この メソッドについての NAME= があった[classname,anker tag]
classNameAry.each{ |cls|
if $Anker[href] && # $Anker[href] is Array of [classname,anker tag]
hrefClass = $Anker[href].assoc(cls)
# cls.html に NAME="href" がある場合
break
end
}
#
# <TD>hash</TD> or <TD><A HREF="Kernel.html#hash">hash</A></TD>
if hrefClass
printf($format0,hrefClass[1],method)
else
printf($format1,method)
end
# class list Fixint < Num < ,,,,,
printf($tail[@right],classNameAry.join("<"))
@right = 1 - @right
end
end # of class define
###################################################################
##################################
# 準備 man にあるアンカー のリストアップ
# ruby-man/*.html から アンカー を抜き取る
Dir.glob($ManDir + "*.html").each{ |manfile|
manFile = open(manfile)
manfile.sub!(/.*\//,"")
classname = manfile.sub(/\.html/,"")
while manFile.gets
if $_ =~ /<A\sNAME\w*="([^"]+)">/i
anker="<A HREF=\"" + manfile + "#" + $1 + "\">"
href = $1.sub(/^[^.]*\./,"class.")
# if class method: Dir.grob --> class.grob
$Anker[href]=Array.new unless $Anker[href]
$Anker[href] << [classname,anker]
end
end
manFile.close
}
#exit
#####################################################################
while line = gets
next if ["class.c","eval.c"].include?(ARGF.filename)
token=line.strip.split(/[\s(),";]+/)
# cKernel = boot_defclass("kernel", 0);
if token[2] == "boot_defclass"
token[3] = "Kernel" if token[3] == "kernel"
$CLASS[token[0]]= CLS.new unless $CLASS[token[0]]
$CLASS[token[0]].setclass(token[3],token[4],"boot")
#cArray = rb_define_class("Array", cObject);
elsif token[2] == "rb_define_class" &&
token[3] != "Data" && token[3] != "nil" &&
token[3] != "true" && token[3] != "false" &&
token[0] !~ /^e/
#rint
token[3] = "MatchData" if token[3] == "MatchingData"
$CLASS[token[0]]= CLS.new unless $CLASS[token[0]]
$CLASS[token[0]].setclass(token[3],token[4],"class")
# module
# included into class
# "Enumerable" "Comparable"
# Enum Compar
# NOT included standalone module
# "Errno" "FileTest" "GC" "ObjectSpace" "Math" "Process"
# FileTest GC ObSpace Math Process
# mEnumerable = rb_define_module("Enumerable");
elsif token[2] == "rb_define_module"
mdl = "standModule"
{ token[3] = "Enum" , mdl="incModule" } if token[3] == "Enumerable"
{ token[3] = "Compar", mdl="incModule" } if token[3] == "Comparable"
token[3] = "ObSpace" if token[3] == "ObjectSpace"
$CLASS[token[0]]= CLS.new unless $CLASS[token[0]]
$CLASS[token[0]].setclass(token[3],nil,mdl)
# rb_define_module_function(mProcess, "uid", proc_getuid, 0);
elsif token[0] == "rb_define_module_function"
$CLASS[token[1]]= CLS.new(token[1]) unless $CLASS[token[1]]
$CLASS[token[1]].setMethod(token[2])
# rb_include_module(cArray, mEnumerable);
elsif token[0] == "rb_include_module"
token[2] = "Enum" if token[2] == "Enumerable"
token[2] = "Compar" if token[2] == "Comparable"
$CLASS[token[1]]= CLS.new(token[1]) unless $CLASS[token[1]]
$CLASS[token[1]].setModule(token[2])
# rb_define_singleton_method(cArray, "new", ary_s_new, -1);
# rb_define_method(cArray, "to_s", ary_to_s, 0);
elsif token[1] != "TopSelf" && token[1] != "cNil" &&
token[1] != "cTrue" && token[1] != "cFalse" &&
token[1] != "cData"
if token[0] == "rb_define_method"
$CLASS[token[1]]= CLS.new(token[1]) unless $CLASS[token[1]]
$CLASS[token[1]].setMethod(token[2])
elsif token[0] == "rb_define_singleton_method"
$CLASS[token[1]]= CLS.new(token[1]) unless $CLASS[token[1]]
$CLASS[token[1]].setClassMethod("class." + token[2])
end
end
end # of while for source gets
############ OUT PUT ########################
############ OUT PUT Index ########################
if $OPT_i
## header ##
print "<HTML>
<HEAD>
<TITLE>組み込みクラスの method Index </TITLE>
</HEAD>
<BODY>
<h3>組み込みクラスの method Index</H3>
"
# get all methods from all class
classMethods = Hash.new
methods = Hash.new
$CLASS.keys.compact.each{ |classID|
next unless ["class","standModule"].include?( $CLASS[ classID ].classtype )
$CLASS[ classID ].allMethod.each{|mthd,classNameAry|
methods[mthd] |= classNameAry if methods[mthd]
methods[mthd] = classNameAry unless methods[mthd]
}
$CLASS[ classID ].allClassMethod.each{|mthd,classNameAry|
classMethods[mthd] |= classNameAry if methods[mthd]
classMethods[mthd] = classNameAry unless methods[mthd]
}
}
# output class method
print "<TABLE BORDER=0>\n<TR><TD>クラスメソッド</TD></TR>\n"
classMethods.keys.sort.each{|methodName|
href=rename(methodName)
method = methodName.dup
method.sub!(/class\./,"")
printf("<TR><TD>%s<TD>",method)
classMethods[methodName].compact.sort.each{|cls|
if $Anker[href] && # $Anker[href] is Array of [classname,anker tag]
hrefClass = $Anker[href].assoc(cls)
printf("<TD>%s%s</TD>",hrefClass[1],cls)
else
printf("<TD>%s</TD>",cls)
end
}
print "</TR>\n"
}
# output method
print "<TR></TR>\n<TR><TD>メソッド</TD></TR>\n"
methods.keys.sort.each{|methodName|
href=rename(methodName)
method = methodName.dup
printf("<TR><TD>%s<TD>",method)
methods[methodName].compact.sort.each{|cls|
if $Anker[href] && # $Anker[href] is Array of [classname,anker tag]
hrefClass = $Anker[href].assoc(cls)
printf("<TD>%s%s</TD>",hrefClass[1],cls)
else
printf("<TD>%s</TD>",cls)
end
}
print "</TR>\n"
}
print "</TABLE>\n"
else
############ OUT PUT Methods ########################
## header ##
print "<HTML>
<HEAD>
<TITLE>組み込みクラスの method</TITLE>
</HEAD>
<BODY>
<h3>組み込みクラスの method</H3>"
## HREF for Classes ##
print "<TABLE BORDER=0>\n"
$CLASS.keys.compact.sort.each{ |classID|
next if $CLASS[ classID ].classtype != "class"
$CLASS[ classID ].printHREFforClass
}
print "<TR></TR><TR><TD>モジュール</TD></TR>\n"
$CLASS.keys.compact.sort.each{ |classID|
next if $CLASS[ classID ].classtype != "standModule"
$CLASS[ classID ].printHREFforClass
}
print "</TABLE><hr>\n"
## Print HREF for method of all classes ##
$CLASS.keys.compact.sort.each{ |classID|
next if $CLASS[ classID ].classtype != "class"
$CLASS[ classID ].printClassHeader
$CLASS[ classID ].printClassMethod
$CLASS[ classID ].printMethod
print "</TABLE>\n"
}
$CLASS.keys.compact.sort.each{ |classID|
next if $CLASS[ classID ].classtype != "standModule"
$CLASS[ classID ].printClassHeader
$CLASS[ classID ].printClassMethod
$CLASS[ classID ].printMethod
print "</TABLE>\n"
}
end
----Next_Part(Tue_Feb__4_23:18:17_1997)----