summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/delegate.rb44
-rw-r--r--lib/eregex.rb39
-rw-r--r--lib/ftools.rb163
-rw-r--r--lib/importenv.rb29
-rw-r--r--lib/mkmf.rb343
-rw-r--r--lib/ostruct.rb55
-rw-r--r--lib/pstore.rb121
-rw-r--r--lib/shellwords.rb48
-rw-r--r--lib/tkdialog.rb62
-rw-r--r--lib/weakref.rb70
10 files changed, 974 insertions, 0 deletions
diff --git a/lib/delegate.rb b/lib/delegate.rb
new file mode 100644
index 0000000000..e5943cead8
--- /dev/null
+++ b/lib/delegate.rb
@@ -0,0 +1,44 @@
+# Delegation class that delegates even methods defined in super class,
+# which can not be covered with normal method_missing hack.
+#
+# Delegater is the abstract delegation class. Need to redefine
+# `__getobj__' method in the subclass. SimpleDelegater is the
+# concrete subclass for simple delegation.
+#
+# Usage:
+# foo = Object.new
+# foo = SimpleDelegater.new(foo)
+# foo.type # => Object
+
+class Delegater
+
+ def initialize(obj)
+ preserved = ["id", "equal?", "__getobj__"]
+ for t in self.type.ancestors
+ preserved |= t.instance_methods
+ break if t == Delegater
+ end
+ for method in obj.methods
+ next if preserved.include? method
+ eval "def self.#{method}(*args); __getobj__.send :#{method}, *args; end"
+ end
+ end
+
+ def __getobj__
+ raise NotImplementError, "need to define `__getobj__'"
+ end
+
+end
+
+class SimpleDelegater<Delegater
+
+ def initialize(obj)
+ super
+ @obj = obj
+ end
+
+ def __getobj__
+ @obj
+ end
+
+end
diff --git a/lib/eregex.rb b/lib/eregex.rb
new file mode 100644
index 0000000000..f214f6a2d4
--- /dev/null
+++ b/lib/eregex.rb
@@ -0,0 +1,39 @@
+
+class RegOr
+ def initialize(re1, re2)
+ @re1 = re1
+ @re2 = re2
+ end
+
+ def =~ (str)
+ @re1 =~ str or @re2 =~ str
+ end
+end
+
+class RegAnd
+ def initialize(re1, re2)
+ @re1 = re1
+ @re2 = re2
+ end
+
+ def =~ (str)
+ @re1 =~ str and @re2 =~ str
+ end
+end
+
+class Regexp
+ def |(other)
+ RegOr.new(self, other)
+ end
+ def &(other)
+ RegAnd.new(self, other)
+ end
+end
+
+p "abc" =~ /b/|/c/
+p "abc" =~ /b/&/c/
+
+
+
+
+
diff --git a/lib/ftools.rb b/lib/ftools.rb
new file mode 100644
index 0000000000..59bc81b365
--- /dev/null
+++ b/lib/ftools.rb
@@ -0,0 +1,163 @@
+class << File
+
+ TOO_BIG = 1024 * 1024 * 2 # 2MB
+
+ def catname from, to
+ if FileTest.directory? to
+ to +
+ if to =~ /\\/
+ if to[-1,1] != '\\' then '\\' end + basename(from)
+ else
+ if to[-1,1] != '/' then '/' end + basename(from)
+ end
+ else
+ to
+ end
+ end
+
+# copy file
+
+ def syscopy from, to
+ to = catname(from, to)
+
+ fsize = size(from)
+ fsize = 1024 if fsize < 512
+ fsize = TOO_BIG if fsize > TOO_BIG
+
+ from = open(from, "r")
+ from.binmode
+ to = open(to, "w")
+ to.binmode
+
+ begin
+ while TRUE
+ r = from.sysread(fsize)
+ rsize = r.size
+ w = 0
+ while w < rsize
+ t = to.syswrite(r[w, rsize - w])
+ w += t
+ end
+ end
+ rescue EOFError
+ ret = TRUE
+ rescue
+ ret = FALSE
+ ensure
+ to.close
+ from.close
+ end
+ ret
+ end
+
+ def copy from, to, verbose = FALSE
+ $stderr.print from, " -> ", catname(from, to), "\n" if verbose
+ syscopy from, to
+ end
+
+ alias cp copy
+
+# move file
+
+ def move from, to, verbose = FALSE
+ to = catname(from, to)
+ $stderr.print from, " -> ", to, "\n" if verbose
+
+ if PLATFORM =~ /djgpp|cygwin32|mswin32/ and FileTest.file? to
+ unlink to
+ end
+ begin
+ rename from, to
+ rescue
+ syscopy from, to and unlink from
+ end
+ end
+
+ alias mv move
+
+# compare two files
+# TRUE: identical
+# FALSE: not identical
+
+ def compare from, to, verbose = FALSE
+ $stderr.print from, " <=> ", to, "\n" if verbose
+ fsize = size(from)
+ fsize = 1024 if fsize < 512
+ fsize = TOO_BIG if fsize > TOO_BIG
+
+ from = open(from, "r")
+ from.binmode
+ to = open(to, "r")
+ to.binmode
+
+ ret = FALSE
+ fr = tr = ''
+
+ begin
+ while fr == tr
+ if fr = from.read(fsize)
+ tr = to.read(fr.size)
+ else
+ ret = !to.read(fsize)
+ break
+ end
+ end
+ rescue
+ ret = FALSE
+ ensure
+ to.close
+ from.close
+ end
+ ret
+ end
+
+ alias cmp compare
+
+# unlink files safely
+
+ def safe_unlink(*files)
+ verbose = if files[-1].is_a? String then FALSE else files.pop end
+ begin
+ $stderr.print files.join(" "), "\n" if verbose
+ chmod 0777, *files
+ unlink *files
+ rescue
+# STDERR.print "warning: Couldn't unlink #{files.join ' '}\n"
+ end
+ end
+
+ alias rm_f safe_unlink
+
+ def makedirs(*dirs)
+ verbose = if dirs[-1].is_a? String then FALSE else dirs.pop end
+# mode = if dirs[-1].is_a? Fixnum then dirs.pop else 0755 end
+ mode = 0755
+ for dir in dirs
+ next if FileTest.directory? dir
+ parent = dirname(dir)
+ makedirs parent unless FileTest.directory? parent
+ $stderr.print "mkdir ", dir, "\n" if verbose
+ Dir.mkdir dir, mode
+ end
+ end
+
+ alias mkpath makedirs
+
+ alias o_chmod chmod
+
+ def chmod(mode, *files)
+ verbose = if files[-1].is_a? String then FALSE else files.pop end
+ $stderr.printf "chmod %04o %s\n", mode, files.join(" ") if verbose
+ o_chmod mode, *files
+ end
+
+ def install(from, to, mode, verbose)
+ to = catname(from, to)
+ unless FileTest.exist? to and cmp from, to
+ cp from, to, verbose
+ chmod mode, to, verbose if mode
+ end
+ end
+
+end
+# vi:set sw=2:
diff --git a/lib/importenv.rb b/lib/importenv.rb
new file mode 100644
index 0000000000..41253765ea
--- /dev/null
+++ b/lib/importenv.rb
@@ -0,0 +1,29 @@
+# importenv.rb -- imports environment variables as global variables
+#
+# Usage:
+#
+# require 'importenv'
+# p $USER
+# $USER = "matz"
+# p ENV["USER"]
+
+for k,v in ENV
+ next unless /^[a-zA-Z][_a-zA-Z0-9]*/ =~ k
+ eval <<EOS
+ $#{k} = %q!#{v}!
+ trace_var "$#{k}", proc{|v|
+ ENV[%q!#{k}!] = v;
+ $#{k} = %q!#{v}!
+ if v == nil
+ untrace_var "$#{k}"
+ end
+ }
+EOS
+end
+
+p $TERM
+$TERM = nil
+p $TERM
+p ENV["TERM"]
+$TERM = "foo"
+p ENV["TERM"]
diff --git a/lib/mkmf.rb b/lib/mkmf.rb
new file mode 100644
index 0000000000..2bf3684920
--- /dev/null
+++ b/lib/mkmf.rb
@@ -0,0 +1,343 @@
+# module to create Makefile for extention modules
+# invoke like: ruby -r mkmf extconf.rb
+
+require 'rbconfig'
+
+include Config
+
+$found = false;
+$lib_cache = {}
+$lib_found = {}
+$func_cache = {}
+$func_found = {}
+$hdr_cache = {}
+$hdr_found = {}
+
+$config_cache = CONFIG["compile_dir"]+"/ext/config.cache"
+if File.exist?($config_cache) then
+ f = open($config_cache, "r")
+ while f.gets
+ case $_
+ when /^lib: (.+) (yes|no)/
+ $lib_cache[$1] = $2
+ when /^func: ([\w_]+) (yes|no)/
+ $func_cache[$1] = $2
+ when /^hdr: (.+) (yes|no)/
+ $hdr_cache[$1] = $2
+ end
+ end
+ f.close
+end
+
+$srcdir = CONFIG["srcdir"]
+$libdir = CONFIG["libdir"]+"/"+CONFIG["ruby_install_name"]
+$archdir = $libdir+"/"+CONFIG["arch"]
+$install = CONFIG["INSTALL_PROGRAM"]
+$install_data = CONFIG["INSTALL_DATA"]
+if $install !~ /^\// then
+ $install = CONFIG["srcdir"]+"/"+$install
+end
+
+if File.exist? $archdir + "/ruby.h"
+ $hdrdir = $archdir
+elsif File.exist? $srcdir + "/ruby.h"
+ $hdrdir = $srcdir
+else
+ STDERR.print "can't find header files for ruby.\n"
+ exit 1
+end
+
+nul = "> /dev/null"
+
+CFLAGS = CONFIG["CFLAGS"]
+if PLATFORM == "m68k-human"
+ nul = "> nul"
+ CFLAGS.gsub!(/-c..-stack=[0-9]+ */, '')
+end
+if $DEBUG
+ nul = ""
+end
+LINK = CONFIG["CC"]+" -o conftest -I#{$srcdir} " + CFLAGS + " %s " + CONFIG["LDFLAGS"] + " %s conftest.c " + CONFIG["LIBS"] + "%s " + nul + " 2>&1"
+CPP = CONFIG["CPP"] + " -E -I#{$srcdir} " + CFLAGS + " %s conftest.c " + nul + " 2>&1"
+
+def try_link(libs)
+ system(format(LINK, $CFLAGS, $LDFLAGS, libs))
+end
+
+def try_cpp
+ system(format(CPP, $CFLAGS))
+end
+
+def have_library(lib, func)
+ printf "checking for %s() in -l%s... ", func, lib
+ STDOUT.flush
+ if $lib_cache[lib]
+ if $lib_cache[lib] == "yes"
+ if $libs
+ $libs = "-l" + lib + " " + $libs
+ else
+ $libs = "-l" + lib
+ end
+ print "(cached) yes\n"
+ return TRUE
+ else
+ print "(cached) no\n"
+ return FALSE
+ end
+ end
+
+ cfile = open("conftest.c", "w")
+ cfile.printf "\
+int main() { return 0; }
+int t() { %s(); return 0; }
+", func
+ cfile.close
+
+ begin
+ if $libs
+ libs = "-l" + lib + " " + $libs
+ else
+ libs = "-l" + lib
+ end
+ unless try_link(libs)
+ $lib_found[lib] = 'no'
+ $found = TRUE
+ print "no\n"
+ return FALSE
+ end
+ ensure
+ system "rm -f conftest*"
+ end
+
+ $libs = libs
+ $lib_found[lib] = 'yes'
+ $found = TRUE
+ print "yes\n"
+ return TRUE
+end
+
+def have_func(func)
+ printf "checking for %s()... ", func
+ STDOUT.flush
+ if $func_cache[func]
+ if $func_cache[func] == "yes"
+ $defs.push(format("-DHAVE_%s", func.upcase))
+ print "(cached) yes\n"
+ return TRUE
+ else
+ print "(cached) no\n"
+ return FALSE
+ end
+ end
+
+ cfile = open("conftest.c", "w")
+ cfile.printf "\
+char %s();
+int main() { return 0; }
+int t() { %s(); return 0; }
+", func, func
+ cfile.close
+
+ libs = $libs
+ libs = "" if libs == nil
+
+ begin
+ unless try_link(libs)
+ $func_found[func] = 'no'
+ $found = TRUE
+ print "no\n"
+ return FALSE
+ end
+ ensure
+ system "rm -f conftest*"
+ end
+ $defs.push(format("-DHAVE_%s", func.upcase))
+ $func_found[func] = 'yes'
+ $found = TRUE
+ print "yes\n"
+ return TRUE
+end
+
+def have_header(header)
+ printf "checking for %s... ", header
+ STDOUT.flush
+ if $hdr_cache[header]
+ if $hdr_cache[header] == "yes"
+ header.tr!("a-z./\055", "A-Z___")
+ $defs.push(format("-DHAVE_%s", header))
+ print "(cached) yes\n"
+ return TRUE
+ else
+ print "(cached) no\n"
+ return FALSE
+ end
+ end
+
+ cfile = open("conftest.c", "w")
+ cfile.printf "\
+#include <%s>
+", header
+ cfile.close
+
+ begin
+ unless try_cpp
+ $hdr_found[header] = 'no'
+ $found = TRUE
+ print "no\n"
+ return FALSE
+ end
+ ensure
+ system "rm -f conftest*"
+ end
+ $hdr_found[header] = 'yes'
+ header.tr!("a-z./\055", "A-Z___")
+ $defs.push(format("-DHAVE_%s", header))
+ $found = TRUE
+ print "yes\n"
+ return TRUE
+end
+
+def create_header()
+ print "creating extconf.h\n"
+ STDOUT.flush
+ if $defs.length > 0
+ hfile = open("extconf.h", "w")
+ for line in $defs
+ line =~ /^-D(.*)/
+ hfile.printf "#define %s 1\n", $1
+ end
+ hfile.close
+ end
+end
+
+def create_makefile(target)
+ print "creating Makefile\n"
+ STDOUT.flush
+ if $libs and CONFIG["DLEXT"] == "o"
+ libs = $libs.split
+ for lib in libs
+ lib.sub!(/-l(.*)/, '"lib\1.a"')
+ end
+ $defs.push(format("-DEXTLIB='%s'", libs.join(",")))
+ end
+ $libs = "" unless $libs
+
+ if !$objs then
+ $objs = Dir["*.c"]
+ for f in $objs
+ f.sub!(/\.(c|cc)$/, ".o")
+ end
+ end
+ $objs = $objs.join(" ")
+
+ mfile = open("Makefile", "w")
+ mfile.print <<EOMF
+SHELL = /bin/sh
+
+#### Start of system configuration section. ####
+
+srcdir = #{$srcdir}
+hdrdir = #{$hdrdir}
+
+CC = gcc
+
+CFLAGS = #{CONFIG["CCDLFLAGS"]} -I#{$hdrdir} #{CFLAGS} #{$CFLAGS} #{$defs.join(" ")}
+DLDFLAGS = #{CONFIG["DLDFLAGS"]} #{$LDFLAGS}
+LDSHARED = #{CONFIG["LDSHARED"]}
+
+prefix = #{CONFIG["prefix"]}
+exec_prefix = #{CONFIG["exec_prefix"]}
+libdir = #{$archdir}
+
+#### End of system configuration section. ####
+
+LOCAL_LIBS = #{$local_libs}
+LIBS = #{$libs}
+OBJS = #{$objs}
+
+TARGET = #{target}.#{CONFIG["DLEXT"]}
+
+INSTALL = #{$install}
+
+binsuffix = #{CONFIG["binsuffix"]}
+
+all: $(TARGET)
+
+clean:; @rm -f *.o *.so *.sl
+ @rm -f Makefile extconf.h conftest.*
+ @rm -f core ruby$(binsuffix) *~
+
+realclean: clean
+
+install: $(libdir)/$(TARGET)
+
+$(libdir)/$(TARGET): $(TARGET)
+ @test -d $(libdir) || mkdir $(libdir)
+ $(INSTALL) $(TARGET) $(libdir)/$(TARGET)
+EOMF
+ for rb in Dir["lib/*.rb"]
+ mfile.printf "\t$(INSTALL) %s %s\n", rb, $libdir
+ end
+ mfile.printf "\n"
+
+ if CONFIG["DLEXT"] != "o"
+ mfile.printf <<EOMF
+$(TARGET): $(OBJS)
+ $(LDSHARED) $(DLDFLAGS) -o $(TARGET) $(OBJS) $(LOCAL_LIBS) $(LIBS)
+EOMF
+ elsif not File.exist?(target + ".c") and not File.exist?(target + ".cc") or
+ mfile.print "$(TARGET): $(OBJS)\n"
+ case PLATFORM
+ when "m68k-human"
+ mfile.printf "ar cru $(TARGET) $(OBJS)\n"
+ when /-nextstep/
+ mfile.printf "cc -r $(CFLAGS) -o $(TARGET) $(OBJS)\n"
+ else
+ mfile.printf "ld $(DLDFLAGS) -r -o $(TARGET) $(OBJS)\n"
+ end
+ end
+
+ if File.exist?("depend")
+ dfile = open("depend", "r")
+ mfile.printf "###\n"
+ while line = dfile.gets()
+ mfile.print line
+ end
+ dfile.close
+ end
+ mfile.close
+
+ if $found
+ begin
+ f = open($config_cache, "w")
+ for k,v in $lib_cache
+ f.printf "lib: %s %s\n", k, v.downcase
+ end
+ for k,v in $lib_found
+ f.printf "lib: %s %s\n", k, v.downcase
+ end
+ for k,v in $func_cache
+ f.printf "func: %s %s\n", k, v.downcase
+ end
+ for k,v in $func_found
+ f.printf "func: %s %s\n", k, v.downcase
+ end
+ for k,v in $hdr_cache
+ f.printf "hdr: %s %s\n", k, v.downcase
+ end
+ for k,v in $hdr_found
+ f.printf "hdr: %s %s\n", k, v.downcase
+ end
+ f.close
+ rescue
+ end
+ end
+end
+
+$local_libs = nil
+$libs = nil
+$objs = nil
+$CFLAGS = nil
+$LDFLAGS = nil
+$defs = []
+
diff --git a/lib/ostruct.rb b/lib/ostruct.rb
new file mode 100644
index 0000000000..f083677d8e
--- /dev/null
+++ b/lib/ostruct.rb
@@ -0,0 +1,55 @@
+# ostruct.rb - Python Style Object
+# just assign to create field
+#
+# s = OpenStruct.new
+# s.foo = 25
+# p s.foo
+# s.bar = 2
+# p s.bar
+# p s
+
+class OpenStruct
+ def initialize(hash=nil)
+ @table = {}
+ if hash
+ for k,v in hash
+ @table[k] = v
+ end
+ end
+ end
+
+ def method_missing(mid, *args)
+ mname = mid.id2name
+ len = args.length
+ if mname =~ /=$/
+ if len != 1
+ raise ArgumentError, "wrong # of arguments (#{len} for 1)", caller(1)
+ end
+ mname.chop!
+ @table[mname] = args[0]
+ elsif args.length == 0
+ @table[mname]
+ else
+ raise NameError, "undefined method `#{mname}'", caller(1)
+ end
+ end
+
+ def delete_field(name)
+ if name.type == Fixnum
+ name = name.id2name
+ end
+ @table.delete name
+ end
+
+ def inspect
+ str = "<#{self.type}"
+ for k,v in @table
+ str += " "
+ str += k
+ str += "="
+ str += v.inspect
+ end
+ str += ">"
+ str
+ end
+end
diff --git a/lib/pstore.rb b/lib/pstore.rb
new file mode 100644
index 0000000000..86f086d226
--- /dev/null
+++ b/lib/pstore.rb
@@ -0,0 +1,121 @@
+#!/usr/local/bin/ruby
+
+# How to use:
+#
+# db = PStore.new("/tmp/foo")
+# db.transaction do
+# p db.roots
+# ary = db["root"] = [1,2,3,4]
+# ary[0] = [1,1.5]
+# end
+
+# db.transaction do
+# p db["root"]
+# end
+
+require "marshal"
+
+class PStore
+ Exception(:Error)
+
+ def initialize(file)
+ dir = File::dirname(file)
+ unless File::directory? dir
+ raise PStore::Error, format("directory %s does not exist", dir)
+ end
+ unless File::writable? dir
+ raise PStore::Error, format("directory %s not writable", dir)
+ end
+ if File::exist? file and not File::readable? file
+ raise PStore::Error, format("file %s not readable", file)
+ end
+ @transaction = false
+ @filename = file
+ @abort = false
+ end
+
+ def in_transaction
+ raise PStore::Error, "not in transaction" unless @transaction
+ end
+ private :in_transaction
+
+ def [](name)
+ in_transaction
+ value = @table[name]
+ if value == nil
+ raise PStore::Error, format("undefined root name `%s'", name)
+ end
+ value
+ end
+ def []=(name, value)
+ in_transaction
+ @table[name] = value
+ end
+
+ def roots
+ in_transaction
+ @table.keys
+ end
+ def root?(name)
+ in_transaction
+ @table.key? name
+ end
+ def path
+ @filename
+ end
+
+ def commit
+ @abort = false
+ throw :pstore_abort_transaction
+ end
+ def abort
+ @abort = true
+ throw :pstore_abort_transaction
+ end
+
+ def transaction
+ raise PStore::Error, "nested transaction" if @transaction
+ begin
+ @transaction = true
+ value = file = nil
+ begin
+ File::open(@filename, "r") do |file|
+ @table = Marshal.load(file)
+ end
+ rescue Errno::ENOENT
+ @table = {}
+ end
+ begin
+ catch(:pstore_abort_transaction) do
+ value = yield(self)
+ end
+ ensure
+ unless @abort
+ File::rename @filename, @filename+"~"
+ begin
+ File::open(@filename, "w") do |file|
+ Marshal::dump(@table, file)
+ end
+ rescue
+ File::rename @filename+"~", @filename
+ end
+ end
+ @abort = false
+ end
+ ensure
+ @transaction = false
+ end
+ value
+ end
+end
+
+db = PStore.new("/tmp/foo")
+db.transaction do
+ p db.roots
+ ary = db["root"] = [1,2,3,4]
+ ary[0] = [1,1.5]
+end
+
+db.transaction do
+ p db["root"]
+end
diff --git a/lib/shellwords.rb b/lib/shellwords.rb
new file mode 100644
index 0000000000..9632f1222a
--- /dev/null
+++ b/lib/shellwords.rb
@@ -0,0 +1,48 @@
+# shellwords.rb
+# original is shellwords.pl
+#
+# Usage:
+# require 'shellwords.rb'
+# words = Shellwords.shellwords(line)
+#
+# or
+#
+# include Shellwords
+# words = shellwords(line)
+
+module Shellwords
+ def shellwords(line)
+ return '' unless line
+ line.sub! /^\s+/, ''
+ words = []
+ while line != ''
+ field = ''
+ while TRUE
+ if line.sub! /^"(([^"\\]|\\.)*)"/, '' then
+ snippet = $1
+ snippet.gsub! /\\(.)/, '\1'
+ elsif line =~ /^"/ then
+ STDOUT.print "Unmatched double quote: $_\n"
+ exit
+ elsif line.sub! /^'(([^'\\]|\\.)*)'/, '' then
+ snippet = $1
+ snippet.gsub! /\\(.)/, '\1'
+ elsif line =~ /^'/ then
+ STDOUT.print "Unmatched single quote: $_\n"
+ exit
+ elsif line.sub! /^\\(.)/, '' then
+ snippet = $1
+ elsif line.sub! /^([^\s\\'"]+)/, '' then
+ snippet = $1
+ else
+ line.sub! /^\s+/, ''
+ break
+ end
+ field += snippet
+ end
+ words += field
+ end
+ words
+ end
+ module_function :shellwords
+end
diff --git a/lib/tkdialog.rb b/lib/tkdialog.rb
new file mode 100644
index 0000000000..e8f2142e07
--- /dev/null
+++ b/lib/tkdialog.rb
@@ -0,0 +1,62 @@
+require "tk"
+
+class TkDialog < TkWindow
+ # initialize tk_dialog
+ def initialize
+ super
+ @var = TkVariable.new
+ id = @var.id
+ INTERP._eval('eval {global '+id+';'+
+ 'set '+id+' [tk_dialog '+
+ @path+" "+title+" \"#{message}\" "+bitmap+" "+
+ default_button+" "+buttons+']}')
+ end
+ def value
+ return @var.value.to_i
+ end
+ ######################################################
+ # #
+ # these methods must be overridden for each dialog #
+ # #
+ ######################################################
+ def title
+ return "DIALOG"
+ end
+ def message
+ return "MESSAGE"
+ end
+ def bitmap
+ return "info"
+ end
+ def default_button
+ return 0
+ end
+ def buttons
+ return "BUTTON1 BUTTON2"
+ end
+end
+
+#
+# dialog for warning
+#
+class TkWarning < TkDialog
+ def initialize(mes)
+ @mes = mes
+ super()
+ end
+ def message
+ return @mes
+ end
+ def title
+ return "WARNING";
+ end
+ def bitmap
+ return "warning";
+ end
+ def default_button
+ return 0;
+ end
+ def buttons
+ return "OK";
+ end
+end
diff --git a/lib/weakref.rb b/lib/weakref.rb
new file mode 100644
index 0000000000..93b2c65ecd
--- /dev/null
+++ b/lib/weakref.rb
@@ -0,0 +1,70 @@
+# Weak Reference class that does not bother GCing.
+#
+# Usage:
+# foo = Object.new
+# foo.hash
+# foo = WeakRef.new(foo)
+# foo.hash
+# ObjectSpace.garbage_collect
+# foo.hash # => Raises WeakRef::RefError (because original GC'ed)
+
+require "delegate"
+
+class WeakRef<Delegater
+
+ Exception :RefError
+
+ ID_MAP = {}
+ ID_REV_MAP = {}
+ ObjectSpace.add_finalizer(lambda{|id|
+ rid = ID_MAP[id]
+ if rid
+ ID_REV_MAP[rid] = nil
+ ID_MAP[id] = nil
+ end
+ rid = ID_REV_MAP[id]
+ if rid
+ ID_REV_MAP[id] = nil
+ ID_MAP[rid] = nil
+ end
+ })
+
+ def initialize(orig)
+ super
+ @id = orig.id
+ ObjectSpace.call_finalizer orig
+ ID_MAP[@id] = self.id
+ ID_REV_MAP[self.id] = @id
+ end
+
+ def __getobj__
+ unless ID_MAP[@id]
+ $@ = caller(1)
+ $! = RefError.new("Illegal Reference - probably recycled")
+ raise
+ end
+ ObjectSpace.id2ref(@id)
+# ObjectSpace.each_object do |obj|
+# return obj if obj.id == @id
+# end
+ end
+
+ def weakref_alive?
+ if ID_MAP[@id]
+ true
+ else
+ false
+ end
+ end
+
+ def []
+ __getobj__
+ end
+end
+
+foo = Object.new
+p foo.hash
+foo = WeakRef.new(foo)
+p foo.hash
+ObjectSpace.garbage_collect
+p foo.hash