読者です 読者をやめる 読者になる 読者になる

Rubydiff

Program Ruby

Ruby のバージョン間の違いを適当に表にしました。

http://shinh.skr.jp/koneta/rubydiff.html

id:rubikitch さんのコードをいじって作りました。

http://d.hatena.ne.jp/rubikitch/20080507/1210091458

あとゴルフ場の Ruby を 1.8.7 にしておきました。

コードはっときます。


class_hierarchy.rb

h = {}
ObjectSpace.each_object(Class){|c| (h[c.superclass] ||= []) << c}
table = h

def walk(table, sup)
  m = []
  table[sup].sort_by{|c|c.name}.each do |c|
    v = {:parent => sup ? sup.name : '*ROOT*'}
    [:instance_methods, :singleton_methods, :constants].each do |t|
      pv = sup ? sup.send(t) : []
      l = c.send(t) - pv
      v[t] = l.map{|_|_.to_s}
    end
    m << [c.name, v]

    m += walk(table, c) if table[c]
  end
  m
end
m = walk(table, nil)
#File.open("#{ARGV[0] || RUBY_VERSION}.dat", 'w') do |of|
#  of.puts m.inspect
#end
puts m.inspect

rubydiff.rb

#!/usr/bin/env ruby

require 'cgi'

m = {}
vers = []
Dir.glob('*.dat').sort.each do |f|
  ver = f[/(.*)\.dat/, 1]
  vers << ver
  #puts f
  m[ver] = eval(File.read(f))
end

puts %Q(<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>

<head>
 <meta http-equiv="CONTENT-TYPE" content="text/html">
 <title>Ruby diff</title>
 <link rev="MADE" href="mailto:shinichiro.hamaji _at_ gmail.com">
 <link rel="INDEX" href=".">
 <link rel="stylesheet" type="text/css" href="/site.css">
</head>

<body>

<h1>Ruby diff</h1>
)

TYPES = [:instance_methods, :singleton_methods, :constants]

table = m
table[vers[-1]].each do |c, v|
  next if /Errno::/ =~ c
  puts "<h2>#{c}</h2>"

  puts "<table border=\"1\" summary=\"#{c}\"><tr><th></th>"
  vers.each do |ver|
    puts "<th>#{ver}</th>"
  end
  puts "</tr><tr><th>parent</th>"

  all = {}
  TYPES.each{|t|all[t] = []}

  vers.each do |ver|
    d = table[ver].assoc(c)
    if d
      TYPES.each do |t|
        all[t] |= d[1][t].map{|m|m.to_s}
      end
      d = d[1][:parent]
    else
      d = 'x'
    end
    puts "<td>#{d}</td>"
  end
  puts "</tr>"

  TYPES.each do |t|
    prefix = {
      :instance_methods => '',
      :singleton_methods => '.',
      :constants => '::'
    }[t]
    all[t].sort_by{|m|m.to_s}.each do |m|
      puts "<tr><th>#{prefix}#{CGI.escapeHTML(m)}</th>"

      vers.each do |ver|
        d = table[ver].assoc(c)
        if d
          d = d[1][t].include?(m) ? 'o' : 'x'
        else
          d = 'x'
        end
        puts "<td>#{d}</td>"
      end

      puts "</tr>"
    end
  end

  puts "</table>"
end

puts '</body></html>'
なにかあれば下記メールアドレスへ。
shinichiro.hamaji _at_ gmail.com
shinichiro.h