mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Merge RDoc changes from HEAD.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@10679 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
4d2d744487
commit
91edcb053b
35 changed files with 361 additions and 321 deletions
|
@ -1,44 +1,51 @@
|
||||||
#
|
#--
|
||||||
# finalizer.rb -
|
# finalizer.rb -
|
||||||
# $Release Version: 0.3$
|
# $Release Version: 0.3$
|
||||||
# $Revision: 1.4 $
|
# $Revision: 1.4 $
|
||||||
# $Date: 1998/02/27 05:34:33 $
|
# $Date: 1998/02/27 05:34:33 $
|
||||||
# by Keiju ISHITSUKA
|
# by Keiju ISHITSUKA
|
||||||
|
#++
|
||||||
#
|
#
|
||||||
# --
|
# Usage:
|
||||||
#
|
|
||||||
# Usage:
|
|
||||||
#
|
#
|
||||||
|
# add dependency R_method(obj, dependant)
|
||||||
# add(obj, dependant, method = :finalize, *opt)
|
# add(obj, dependant, method = :finalize, *opt)
|
||||||
# add_dependency(obj, dependant, method = :finalize, *opt)
|
# add_dependency(obj, dependant, method = :finalize, *opt)
|
||||||
# add dependency R_method(obj, dependant)
|
|
||||||
#
|
#
|
||||||
|
# delete dependency R_method(obj, dependant)
|
||||||
# delete(obj_or_id, dependant, method = :finalize)
|
# delete(obj_or_id, dependant, method = :finalize)
|
||||||
# delete_dependency(obj_or_id, dependant, method = :finalize)
|
# delete_dependency(obj_or_id, dependant, method = :finalize)
|
||||||
# delete dependency R_method(obj, dependant)
|
|
||||||
# delete_all_dependency(obj_or_id, dependant)
|
|
||||||
# delete dependency R_*(obj, dependant)
|
|
||||||
# delete_by_dependant(dependant, method = :finalize)
|
|
||||||
# delete dependency R_method(*, dependant)
|
|
||||||
# delete_all_by_dependant(dependant)
|
|
||||||
# delete dependency R_*(*, dependant)
|
|
||||||
# delete_all
|
|
||||||
# delete all dependency R_*(*, *)
|
|
||||||
#
|
#
|
||||||
|
# delete dependency R_*(obj, dependant)
|
||||||
|
# delete_all_dependency(obj_or_id, dependant)
|
||||||
|
#
|
||||||
|
# delete dependency R_method(*, dependant)
|
||||||
|
# delete_by_dependant(dependant, method = :finalize)
|
||||||
|
#
|
||||||
|
# delete dependency R_*(*, dependant)
|
||||||
|
# delete_all_by_dependant(dependant)
|
||||||
|
#
|
||||||
|
# delete all dependency R_*(*, *)
|
||||||
|
# delete_all
|
||||||
|
#
|
||||||
|
# finalize the dependant connected by dependency R_method(obj, dependtant).
|
||||||
# finalize(obj_or_id, dependant, method = :finalize)
|
# finalize(obj_or_id, dependant, method = :finalize)
|
||||||
# finalize_dependency(obj_or_id, dependant, method = :finalize)
|
# finalize_dependency(obj_or_id, dependant, method = :finalize)
|
||||||
# finalize the dependant connected by dependency R_method(obj, dependtant).
|
|
||||||
# finalize_all_dependency(obj_or_id, dependant)
|
|
||||||
# finalize all dependants connected by dependency R_*(obj, dependtant).
|
|
||||||
# finalize_by_dependant(dependant, method = :finalize)
|
|
||||||
# finalize the dependant connected by dependency R_method(*, dependtant).
|
|
||||||
# finalize_all_by_dependant(dependant)
|
|
||||||
# finalize all dependants connected by dependency R_*(*, dependant).
|
|
||||||
# finalize_all
|
|
||||||
# finalize all dependency registered to the Finalizer.
|
|
||||||
#
|
#
|
||||||
|
# finalize all dependants connected by dependency R_*(obj, dependtant).
|
||||||
|
# finalize_all_dependency(obj_or_id, dependant)
|
||||||
|
#
|
||||||
|
# finalize the dependant connected by dependency R_method(*, dependtant).
|
||||||
|
# finalize_by_dependant(dependant, method = :finalize)
|
||||||
|
#
|
||||||
|
# finalize all dependants connected by dependency R_*(*, dependant).
|
||||||
|
# finalize_all_by_dependant(dependant)
|
||||||
|
#
|
||||||
|
# finalize all dependency registered to the Finalizer.
|
||||||
|
# finalize_all
|
||||||
|
#
|
||||||
|
# stop invoking Finalizer on GC.
|
||||||
# safe{..}
|
# safe{..}
|
||||||
# stop invoking Finalizer on GC.
|
|
||||||
#
|
#
|
||||||
|
|
||||||
module Finalizer
|
module Finalizer
|
||||||
|
|
|
@ -11,25 +11,22 @@
|
||||||
#
|
#
|
||||||
# == Description
|
# == Description
|
||||||
#
|
#
|
||||||
# +ftools+ adds several (class, not instance) methods to the File class, for copying, moving,
|
# ftools adds several (class, not instance) methods to the File class, for
|
||||||
# deleting, installing, and comparing files, as well as creating a directory path. See the
|
# copying, moving, deleting, installing, and comparing files, as well as
|
||||||
# File class for details.
|
# creating a directory path. See the File class for details.
|
||||||
#
|
#
|
||||||
# +fileutils+ contains all or nearly all the same functionality and more, and is a recommended
|
# FileUtils contains all or nearly all the same functionality and more, and
|
||||||
# option over +ftools+.
|
# is a recommended option over ftools
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# When you
|
# When you
|
||||||
#
|
#
|
||||||
# require 'ftools'
|
# require 'ftools'
|
||||||
#
|
#
|
||||||
# then the File class aquires some utility methods for copying, moving, and deleting files, and
|
# then the File class aquires some utility methods for copying, moving, and
|
||||||
# more.
|
# deleting files, and more.
|
||||||
#
|
#
|
||||||
# See the method descriptions below, and consider using +fileutils+ as it is more
|
# See the method descriptions below, and consider using FileUtils as it is
|
||||||
# comprehensive.
|
# more comprehensive.
|
||||||
#
|
#
|
||||||
class File
|
class File
|
||||||
end
|
end
|
||||||
|
@ -96,8 +93,8 @@ class << File
|
||||||
|
|
||||||
#
|
#
|
||||||
# Moves a file +from+ to +to+ using #syscopy. If +to+ is a directory,
|
# Moves a file +from+ to +to+ using #syscopy. If +to+ is a directory,
|
||||||
# copies from +from+ to <tt>to/from</tt>. If +verbose+ is true, <tt>from -> to</tt>
|
# copies from +from+ to <tt>to/from</tt>. If +verbose+ is true, <tt>from ->
|
||||||
# is printed.
|
# to</tt> is printed.
|
||||||
#
|
#
|
||||||
def move(from, to, verbose = false)
|
def move(from, to, verbose = false)
|
||||||
to = catname(from, to)
|
to = catname(from, to)
|
||||||
|
@ -127,7 +124,7 @@ class << File
|
||||||
alias mv move
|
alias mv move
|
||||||
|
|
||||||
#
|
#
|
||||||
# Returns +true+ iff the contents of files +from+ and +to+ are
|
# Returns +true+ if and only if the contents of files +from+ and +to+ are
|
||||||
# identical. If +verbose+ is +true+, <tt>from <=> to</tt> is printed.
|
# identical. If +verbose+ is +true+, <tt>from <=> to</tt> is printed.
|
||||||
#
|
#
|
||||||
def compare(from, to, verbose = false)
|
def compare(from, to, verbose = false)
|
||||||
|
|
|
@ -19,6 +19,7 @@ warn "Warning:#{caller[0].sub(/:in `.*'\z/, '')}: getopts is deprecated after Ru
|
||||||
|
|
||||||
$RCS_ID=%q$Header$
|
$RCS_ID=%q$Header$
|
||||||
|
|
||||||
|
# getopts is obsolete. Use GetoptLong.
|
||||||
|
|
||||||
def getopts(single_options, *options)
|
def getopts(single_options, *options)
|
||||||
boolopts = {}
|
boolopts = {}
|
||||||
|
|
|
@ -12,21 +12,23 @@ require "socket"
|
||||||
require "thread"
|
require "thread"
|
||||||
|
|
||||||
#
|
#
|
||||||
# +GServer+ implements a generic server, featuring thread pool management, simple logging, and
|
# GServer implements a generic server, featuring thread pool management,
|
||||||
# multi-server management. See <tt>xmlrpc/httpserver.rb</tt> in the Ruby standard library for
|
# simple logging, and multi-server management. See HttpServer in
|
||||||
# an example of +GServer+ in action.
|
# <tt>xmlrpc/httpserver.rb</tt> in the Ruby standard library for an example of
|
||||||
|
# GServer in action.
|
||||||
#
|
#
|
||||||
# Any kind of application-level server can be implemented using this class. It accepts
|
# Any kind of application-level server can be implemented using this class.
|
||||||
# multiple simultaneous connections from clients, up to an optional maximum number. Several
|
# It accepts multiple simultaneous connections from clients, up to an optional
|
||||||
# _services_ (i.e. one service per TCP port) can be run simultaneously, and stopped at any time
|
# maximum number. Several _services_ (i.e. one service per TCP port) can be
|
||||||
# through the class method <tt>GServer.stop(port)</tt>. All the threading issues are handled,
|
# run simultaneously, and stopped at any time through the class method
|
||||||
# saving you the effort. All events are optionally logged, but you can provide your own event
|
# <tt>GServer.stop(port)</tt>. All the threading issues are handled, saving
|
||||||
# handlers if you wish.
|
# you the effort. All events are optionally logged, but you can provide your
|
||||||
|
# own event handlers if you wish.
|
||||||
#
|
#
|
||||||
# === Example
|
# === Example
|
||||||
#
|
#
|
||||||
# Using +GServer+ is simple. Below we implement a simple time server, run it, query it, and
|
# Using GServer is simple. Below we implement a simple time server, run it,
|
||||||
# shut it down. Try this code in +irb+:
|
# query it, and shut it down. Try this code in +irb+:
|
||||||
#
|
#
|
||||||
# require 'gserver'
|
# require 'gserver'
|
||||||
#
|
#
|
||||||
|
@ -60,14 +62,16 @@ require "thread"
|
||||||
# GServer.stop(10001)
|
# GServer.stop(10001)
|
||||||
# # or, of course, "server.stop".
|
# # or, of course, "server.stop".
|
||||||
#
|
#
|
||||||
# All the business of accepting connections and exception handling is taken care of. All we
|
# All the business of accepting connections and exception handling is taken
|
||||||
# have to do is implement the method that actually serves the client.
|
# care of. All we have to do is implement the method that actually serves the
|
||||||
|
# client.
|
||||||
#
|
#
|
||||||
# === Advanced
|
# === Advanced
|
||||||
#
|
#
|
||||||
# As the example above shows, the way to use +GServer+ is to subclass it to create a specific
|
# As the example above shows, the way to use GServer is to subclass it to
|
||||||
# server, overriding the +serve+ method. You can override other methods as well if you wish,
|
# create a specific server, overriding the +serve+ method. You can override
|
||||||
# perhaps to collect statistics, or emit more detailed logging.
|
# other methods as well if you wish, perhaps to collect statistics, or emit
|
||||||
|
# more detailed logging.
|
||||||
#
|
#
|
||||||
# connecting
|
# connecting
|
||||||
# disconnecting
|
# disconnecting
|
||||||
|
@ -76,8 +80,8 @@ require "thread"
|
||||||
#
|
#
|
||||||
# The above methods are only called if auditing is enabled.
|
# The above methods are only called if auditing is enabled.
|
||||||
#
|
#
|
||||||
# You can also override +log+ and +error+ if, for example, you wish to use a more sophisticated
|
# You can also override +log+ and +error+ if, for example, you wish to use a
|
||||||
# logging system.
|
# more sophisticated logging system.
|
||||||
#
|
#
|
||||||
class GServer
|
class GServer
|
||||||
|
|
||||||
|
|
|
@ -7,29 +7,9 @@
|
||||||
# You can redistribute and/or modify it under the same terms as Ruby.
|
# You can redistribute and/or modify it under the same terms as Ruby.
|
||||||
#
|
#
|
||||||
# $Id$
|
# $Id$
|
||||||
#--
|
#
|
||||||
# TODO:
|
# TODO:
|
||||||
# - scope_id support
|
# - scope_id support
|
||||||
#++
|
|
||||||
#
|
|
||||||
#== Example
|
|
||||||
#
|
|
||||||
# require 'ipaddr'
|
|
||||||
#
|
|
||||||
# ipaddr1 = IPAddr.new "3ffe:505:2::1"
|
|
||||||
#
|
|
||||||
# p ipaddr1 #=> #<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>
|
|
||||||
#
|
|
||||||
# p ipaddr1.to_s #=> "3ffe:505:2::1"
|
|
||||||
#
|
|
||||||
# ipaddr2 = ipaddr1.mask(48) #=> #<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0000/ffff:ffff:ffff:0000:0000:0000:0000:0000>
|
|
||||||
#
|
|
||||||
# p ipaddr2.to_s #=> "3ffe:505:2::"
|
|
||||||
#
|
|
||||||
# ipaddr3 = IPAddr.new "192.168.2.0/24"
|
|
||||||
#
|
|
||||||
# p ipaddr3 #=> #<IPAddr: IPv4:192.168.2.0/255.255.255.0>
|
|
||||||
|
|
||||||
require 'socket'
|
require 'socket'
|
||||||
|
|
||||||
unless Socket.const_defined? "AF_INET6"
|
unless Socket.const_defined? "AF_INET6"
|
||||||
|
@ -75,8 +55,27 @@ unless Socket.const_defined? "AF_INET6"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# IPAddr provides a set of methods to manipulate an IP address. Both
|
# IPAddr provides a set of methods to manipulate an IP address. Both IPv4 and
|
||||||
# IPv4 and IPv6 are supported.
|
# IPv6 are supported.
|
||||||
|
#
|
||||||
|
# == Example
|
||||||
|
#
|
||||||
|
# require 'ipaddr'
|
||||||
|
#
|
||||||
|
# ipaddr1 = IPAddr.new "3ffe:505:2::1"
|
||||||
|
#
|
||||||
|
# p ipaddr1 #=> #<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>
|
||||||
|
#
|
||||||
|
# p ipaddr1.to_s #=> "3ffe:505:2::1"
|
||||||
|
#
|
||||||
|
# ipaddr2 = ipaddr1.mask(48) #=> #<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0000/ffff:ffff:ffff:0000:0000:0000:0000:0000>
|
||||||
|
#
|
||||||
|
# p ipaddr2.to_s #=> "3ffe:505:2::"
|
||||||
|
#
|
||||||
|
# ipaddr3 = IPAddr.new "192.168.2.0/24"
|
||||||
|
#
|
||||||
|
# p ipaddr3 #=> #<IPAddr: IPv4:192.168.2.0/255.255.255.0>
|
||||||
|
|
||||||
class IPAddr
|
class IPAddr
|
||||||
|
|
||||||
IN4MASK = 0xffffffff
|
IN4MASK = 0xffffffff
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
# logger.rb - saimple logging utility
|
# logger.rb - saimple logging utility
|
||||||
# Copyright (C) 2000-2003, 2005 NAKAMURA, Hiroshi <nakahiro@sarion.co.jp>.
|
# Copyright (C) 2000-2003, 2005 NAKAMURA, Hiroshi <nakahiro@sarion.co.jp>.
|
||||||
|
|
||||||
|
require 'monitor'
|
||||||
|
|
||||||
# = logger.rb
|
|
||||||
#
|
|
||||||
# Simple logging utility.
|
# Simple logging utility.
|
||||||
#
|
#
|
||||||
# Author:: NAKAMURA, Hiroshi <nakahiro@sarion.co.jp>
|
# Author:: NAKAMURA, Hiroshi <nakahiro@sarion.co.jp>
|
||||||
|
@ -12,14 +11,6 @@
|
||||||
# You can redistribute it and/or modify it under the same terms of Ruby's
|
# You can redistribute it and/or modify it under the same terms of Ruby's
|
||||||
# license; either the dual license version in 2003, or any later version.
|
# license; either the dual license version in 2003, or any later version.
|
||||||
# Revision:: $Id$
|
# Revision:: $Id$
|
||||||
#
|
|
||||||
# See Logger for documentation.
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
require 'monitor'
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# == Description
|
# == Description
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,5 +1,14 @@
|
||||||
|
# The Mail class represents an internet mail message (as per RFC822, RFC2822)
|
||||||
|
# with headers and a body.
|
||||||
class Mail
|
class Mail
|
||||||
|
|
||||||
|
# Create a new Mail where +f+ is either a stream which responds to gets(),
|
||||||
|
# or a path to a file. If +f+ is a path it will be opened.
|
||||||
|
#
|
||||||
|
# The whole message is read so it can be made available through the #header,
|
||||||
|
# #[] and #body methods.
|
||||||
|
#
|
||||||
|
# The "From " line is ignored if the mail is in mbox format.
|
||||||
def initialize(f)
|
def initialize(f)
|
||||||
unless defined? f.gets
|
unless defined? f.gets
|
||||||
f = open(f, "r")
|
f = open(f, "r")
|
||||||
|
@ -34,14 +43,19 @@ class Mail
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Return the headers as a Hash.
|
||||||
def header
|
def header
|
||||||
return @header
|
return @header
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Return the message body as an Array of lines
|
||||||
def body
|
def body
|
||||||
return @body
|
return @body
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Return the header corresponding to +field+.
|
||||||
|
#
|
||||||
|
# Matching is case-insensitive.
|
||||||
def [](field)
|
def [](field)
|
||||||
@header[field.capitalize]
|
@header[field.capitalize]
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#
|
#--
|
||||||
# mutex_m.rb -
|
# mutex_m.rb -
|
||||||
# $Release Version: 3.0$
|
# $Release Version: 3.0$
|
||||||
# $Revision: 1.7 $
|
# $Revision: 1.7 $
|
||||||
|
@ -7,22 +7,26 @@
|
||||||
# by Keiju ISHITSUKA(keiju@ishitsuka.com)
|
# by Keiju ISHITSUKA(keiju@ishitsuka.com)
|
||||||
# modified by matz
|
# modified by matz
|
||||||
# patched by akira yamada
|
# patched by akira yamada
|
||||||
|
#++
|
||||||
#
|
#
|
||||||
# --
|
# == Usage
|
||||||
# Usage:
|
|
||||||
# require "mutex_m.rb"
|
|
||||||
# obj = Object.new
|
|
||||||
# obj.extend Mutex_m
|
|
||||||
# ...
|
|
||||||
# extended object can be handled like Mutex
|
|
||||||
# or
|
|
||||||
# class Foo
|
|
||||||
# include Mutex_m
|
|
||||||
# ...
|
|
||||||
# end
|
|
||||||
# obj = Foo.new
|
|
||||||
# this obj can be handled like Mutex
|
|
||||||
#
|
#
|
||||||
|
# Extend an object and use it like a Mutex object:
|
||||||
|
#
|
||||||
|
# require "mutex_m.rb"
|
||||||
|
# obj = Object.new
|
||||||
|
# obj.extend Mutex_m
|
||||||
|
# # ...
|
||||||
|
#
|
||||||
|
# Or, include Mutex_m in a class to have its instances behave like a Mutex
|
||||||
|
# object:
|
||||||
|
#
|
||||||
|
# class Foo
|
||||||
|
# include Mutex_m
|
||||||
|
# # ...
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# obj = Foo.new
|
||||||
|
|
||||||
module Mutex_m
|
module Mutex_m
|
||||||
def Mutex_m.define_aliases(cl)
|
def Mutex_m.define_aliases(cl)
|
||||||
|
|
109
lib/open-uri.rb
109
lib/open-uri.rb
|
@ -1,59 +1,3 @@
|
||||||
#= open-uri.rb
|
|
||||||
#
|
|
||||||
#open-uri.rb is easy-to-use wrapper for net/http, net/https and net/ftp.
|
|
||||||
#
|
|
||||||
#== Example
|
|
||||||
#
|
|
||||||
#It is possible to open http/https/ftp URL as usual a file:
|
|
||||||
#
|
|
||||||
# open("http://www.ruby-lang.org/") {|f|
|
|
||||||
# f.each_line {|line| p line}
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
#The opened file has several methods for meta information as follows since
|
|
||||||
#it is extended by OpenURI::Meta.
|
|
||||||
#
|
|
||||||
# open("http://www.ruby-lang.org/en") {|f|
|
|
||||||
# f.each_line {|line| p line}
|
|
||||||
# p f.base_uri # <URI::HTTP:0x40e6ef2 URL:http://www.ruby-lang.org/en/>
|
|
||||||
# p f.content_type # "text/html"
|
|
||||||
# p f.charset # "iso-8859-1"
|
|
||||||
# p f.content_encoding # []
|
|
||||||
# p f.last_modified # Thu Dec 05 02:45:02 UTC 2002
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
#Additional header fields can be specified by an optional hash argument.
|
|
||||||
#
|
|
||||||
# open("http://www.ruby-lang.org/en/",
|
|
||||||
# "User-Agent" => "Ruby/#{RUBY_VERSION}",
|
|
||||||
# "From" => "foo@bar.invalid",
|
|
||||||
# "Referer" => "http://www.ruby-lang.org/") {|f|
|
|
||||||
# ...
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
#The environment variables such as http_proxy, https_proxy and ftp_proxy
|
|
||||||
#are in effect by default. :proxy => nil disables proxy.
|
|
||||||
#
|
|
||||||
# open("http://www.ruby-lang.org/en/raa.html",
|
|
||||||
# :proxy => nil) {|f|
|
|
||||||
# ...
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
#URI objects can be opened in similar way.
|
|
||||||
#
|
|
||||||
# uri = URI.parse("http://www.ruby-lang.org/en/")
|
|
||||||
# uri.open {|f|
|
|
||||||
# ...
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
#URI objects can be read directly.
|
|
||||||
#The returned string is also extended by OpenURI::Meta.
|
|
||||||
#
|
|
||||||
# str = uri.read
|
|
||||||
# p str.base_uri
|
|
||||||
#
|
|
||||||
#Author:: Tanaka Akira <akr@m17n.org>
|
|
||||||
|
|
||||||
require 'uri'
|
require 'uri'
|
||||||
require 'stringio'
|
require 'stringio'
|
||||||
require 'time'
|
require 'time'
|
||||||
|
@ -91,6 +35,59 @@ module Kernel
|
||||||
module_function :open
|
module_function :open
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# OpenURI is an easy-to-use wrapper for net/http, net/https and net/ftp.
|
||||||
|
#
|
||||||
|
#== Example
|
||||||
|
#
|
||||||
|
# It is possible to open http/https/ftp URL as usual like opening a file:
|
||||||
|
#
|
||||||
|
# open("http://www.ruby-lang.org/") {|f|
|
||||||
|
# f.each_line {|line| p line}
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# The opened file has several methods for meta information as follows since
|
||||||
|
# it is extended by OpenURI::Meta.
|
||||||
|
#
|
||||||
|
# open("http://www.ruby-lang.org/en") {|f|
|
||||||
|
# f.each_line {|line| p line}
|
||||||
|
# p f.base_uri # <URI::HTTP:0x40e6ef2 URL:http://www.ruby-lang.org/en/>
|
||||||
|
# p f.content_type # "text/html"
|
||||||
|
# p f.charset # "iso-8859-1"
|
||||||
|
# p f.content_encoding # []
|
||||||
|
# p f.last_modified # Thu Dec 05 02:45:02 UTC 2002
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# Additional header fields can be specified by an optional hash argument.
|
||||||
|
#
|
||||||
|
# open("http://www.ruby-lang.org/en/",
|
||||||
|
# "User-Agent" => "Ruby/#{RUBY_VERSION}",
|
||||||
|
# "From" => "foo@bar.invalid",
|
||||||
|
# "Referer" => "http://www.ruby-lang.org/") {|f|
|
||||||
|
# # ...
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# The environment variables such as http_proxy, https_proxy and ftp_proxy
|
||||||
|
# are in effect by default. :proxy => nil disables proxy.
|
||||||
|
#
|
||||||
|
# open("http://www.ruby-lang.org/en/raa.html", :proxy => nil) {|f|
|
||||||
|
# # ...
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# URI objects can be opened in a similar way.
|
||||||
|
#
|
||||||
|
# uri = URI.parse("http://www.ruby-lang.org/en/")
|
||||||
|
# uri.open {|f|
|
||||||
|
# # ...
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# URI objects can be read directly. The returned string is also extended by
|
||||||
|
# OpenURI::Meta.
|
||||||
|
#
|
||||||
|
# str = uri.read
|
||||||
|
# p str.base_uri
|
||||||
|
#
|
||||||
|
# Author:: Tanaka Akira <akr@m17n.org>
|
||||||
|
|
||||||
module OpenURI
|
module OpenURI
|
||||||
Options = {
|
Options = {
|
||||||
:proxy => true,
|
:proxy => true,
|
||||||
|
|
22
lib/open3.rb
22
lib/open3.rb
|
@ -3,12 +3,24 @@
|
||||||
# which IO#popen does not allow)
|
# which IO#popen does not allow)
|
||||||
#
|
#
|
||||||
# Usage:
|
# Usage:
|
||||||
# require "open3"
|
|
||||||
#
|
#
|
||||||
# stdin, stdout, stderr = Open3.popen3('nroff -man')
|
# require "open3"
|
||||||
# or
|
#
|
||||||
# include Open3
|
# stdin, stdout, stderr = Open3.popen3('nroff -man')
|
||||||
# stdin, stdout, stderr = popen3('nroff -man')
|
#
|
||||||
|
# or:
|
||||||
|
#
|
||||||
|
# include Open3
|
||||||
|
#
|
||||||
|
# stdin, stdout, stderr = popen3('nroff -man')
|
||||||
|
#
|
||||||
|
# popen3 can also take a block which will receive stdin, stdout and stderr as
|
||||||
|
# parameters. This ensures stdin, stdout and stderr are closed once the block
|
||||||
|
# exits.
|
||||||
|
#
|
||||||
|
# Such as:
|
||||||
|
#
|
||||||
|
# Open3.popen3('nroff -man') { |stdin, stdout, stderr| ... }
|
||||||
|
|
||||||
module Open3
|
module Open3
|
||||||
#[stdin, stdout, stderr] = popen3(command);
|
#[stdin, stdout, stderr] = popen3(command);
|
||||||
|
|
|
@ -25,24 +25,22 @@
|
||||||
#
|
#
|
||||||
# === Object relationship diagram
|
# === Object relationship diagram
|
||||||
#
|
#
|
||||||
# +--------------+
|
# +--------------+
|
||||||
# | OptionParser |<>-----+
|
# | OptionParser |<>-----+
|
||||||
# +--------------+ | +--------+
|
# +--------------+ | +--------+
|
||||||
# | ,-| Switch |
|
# | ,-| Switch |
|
||||||
# on_head -------->+---------------+ / +--------+
|
# on_head -------->+---------------+ / +--------+
|
||||||
# accept/reject -->| List |<|>-
|
# accept/reject -->| List |<|>-
|
||||||
# | |<|>- +----------+
|
# | |<|>- +----------+
|
||||||
# on ------------->+---------------+ `-| argument |
|
# on ------------->+---------------+ `-| argument |
|
||||||
# : : | class |
|
# : : | class |
|
||||||
# +---------------+ |==========|
|
# +---------------+ |==========|
|
||||||
# on_tail -------->| | |pattern |
|
# on_tail -------->| | |pattern |
|
||||||
# +---------------+ |----------|
|
# +---------------+ |----------|
|
||||||
# OptionParser.accept ->| DefaultList | |converter |
|
# OptionParser.accept ->| DefaultList | |converter |
|
||||||
# reject |(shared between| +----------+
|
# reject |(shared between| +----------+
|
||||||
# | all instances)|
|
# | all instances)|
|
||||||
# +---------------+
|
# +---------------+
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# == OptionParser
|
# == OptionParser
|
||||||
#
|
#
|
||||||
|
|
|
@ -57,6 +57,8 @@ def setExpression(ex, opt, op)
|
||||||
return ex
|
return ex
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# parseArgs is obsolete. Use OptionParser instead.
|
||||||
|
|
||||||
def parseArgs(argc, nopt, single_opts, *opts)
|
def parseArgs(argc, nopt, single_opts, *opts)
|
||||||
if (noOptions = getopts(single_opts, *opts)) == nil
|
if (noOptions = getopts(single_opts, *opts)) == nil
|
||||||
printUsageAndExit()
|
printUsageAndExit()
|
||||||
|
|
39
lib/ping.rb
39
lib/ping.rb
|
@ -1,46 +1,35 @@
|
||||||
#
|
#
|
||||||
# ping.rb -- check a host for upness
|
# ping.rb -- check a host for upness
|
||||||
#
|
#
|
||||||
|
|
||||||
|
require 'timeout'
|
||||||
|
require "socket"
|
||||||
|
|
||||||
#= SYNOPSIS
|
#= SYNOPSIS
|
||||||
#
|
#
|
||||||
# require 'ping'
|
# require 'ping'
|
||||||
# print "'jimmy' is alive and kicking\n" if Ping.pingecho('jimmy', 10) ;
|
#
|
||||||
|
# puts "'jimmy' is alive and kicking" if Ping.pingecho('jimmy', 10)
|
||||||
#
|
#
|
||||||
#= DESCRIPTION
|
#= DESCRIPTION
|
||||||
#
|
#
|
||||||
# This module contains routines to test for the reachability of remote hosts.
|
# This module contains routines to test for the reachability of remote hosts.
|
||||||
# Currently the only routine implemented is pingecho().
|
# Currently the only routine implemented is pingecho().
|
||||||
#
|
#
|
||||||
# pingecho() uses a TCP echo (I<not> an ICMP one) to determine if the
|
# pingecho() uses a TCP echo (_not_ an ICMP echo) to determine if the
|
||||||
# remote host is reachable. This is usually adequate to tell that a remote
|
# remote host is reachable. This is usually adequate to tell that a remote
|
||||||
# host is available to rsh(1), ftp(1), or telnet(1) onto.
|
# host is available to rsh(1), ftp(1), or telnet(1) to.
|
||||||
#
|
|
||||||
#== Parameters
|
|
||||||
#
|
|
||||||
# : hostname
|
|
||||||
#
|
|
||||||
# The remote host to check, specified either as a hostname or as an
|
|
||||||
# IP address.
|
|
||||||
#
|
|
||||||
# : timeout
|
|
||||||
#
|
|
||||||
# The timeout in seconds. If not specified it will default to 5 seconds.
|
|
||||||
#
|
|
||||||
# : service
|
|
||||||
#
|
|
||||||
# The service port to connect. The default is "echo".
|
|
||||||
#
|
#
|
||||||
#= WARNING
|
#= WARNING
|
||||||
#
|
#
|
||||||
# pingecho() uses user-level thread to implement the timeout, so it may block
|
# pingecho() may block for a long period if name resolution is slow. Require
|
||||||
# for long period if named does not respond for some reason.
|
# 'resolv-replace' to use non-blocking name resolution.
|
||||||
#
|
#
|
||||||
#=end
|
|
||||||
|
|
||||||
require 'timeout'
|
|
||||||
require "socket"
|
|
||||||
|
|
||||||
module Ping
|
module Ping
|
||||||
|
|
||||||
|
# return true if we can open a connection to the hostname or IP address
|
||||||
|
# +host+ on port +service+ (which defaults to the "echo" port) waiting up to
|
||||||
|
# +timeout+ seconds.
|
||||||
def pingecho(host, timeout=5, service="echo")
|
def pingecho(host, timeout=5, service="echo")
|
||||||
begin
|
begin
|
||||||
timeout(timeout) do
|
timeout(timeout) do
|
||||||
|
|
|
@ -82,9 +82,6 @@ RDoc is Copyright (c) 2001-2003 Dave Thomas, The Pragmatic Programmers. It
|
||||||
is free software, and may be redistributed under the terms specified
|
is free software, and may be redistributed under the terms specified
|
||||||
in the README file of the Ruby distribution.
|
in the README file of the Ruby distribution.
|
||||||
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
= Usage
|
= Usage
|
||||||
|
|
||||||
RDoc is invoked from the command line using:
|
RDoc is invoked from the command line using:
|
||||||
|
|
|
@ -21,6 +21,8 @@ require 'ftools'
|
||||||
# clutter.
|
# clutter.
|
||||||
#
|
#
|
||||||
# ToDo: This isn't universally true.
|
# ToDo: This isn't universally true.
|
||||||
|
#
|
||||||
|
# :include: README
|
||||||
|
|
||||||
module RDoc
|
module RDoc
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
# readbytes.rb
|
# TruncatedDataError is raised when IO#readbytes fails to read enough data.
|
||||||
#
|
|
||||||
# add IO#readbytes, which reads fixed sized data.
|
|
||||||
# it guarantees read data size.
|
|
||||||
|
|
||||||
class TruncatedDataError<IOError
|
class TruncatedDataError<IOError
|
||||||
def initialize(mesg, data)
|
def initialize(mesg, data) # :nodoc:
|
||||||
@data = data
|
@data = data
|
||||||
super(mesg)
|
super(mesg)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# The read portion of an IO#readbytes attempt.
|
||||||
attr_reader :data
|
attr_reader :data
|
||||||
end
|
end
|
||||||
|
|
||||||
class IO
|
class IO
|
||||||
# reads exactly n bytes from the IO stream.
|
# Reads exactly +n+ bytes.
|
||||||
# If the data read is nil, raises EOFError.
|
#
|
||||||
# If the data read is too short, raises TruncatedDataError.
|
# If the data read is nil an EOFError is raised.
|
||||||
# The method TruncatedDataError#data may be used to obtain
|
#
|
||||||
# the truncated message.
|
# If the data read is too short a TruncatedDataError is raised and the read
|
||||||
|
# data is obtainable via its #data method.
|
||||||
def readbytes(n)
|
def readbytes(n)
|
||||||
str = read(n)
|
str = read(n)
|
||||||
if str == nil
|
if str == nil
|
||||||
|
|
|
@ -2,13 +2,15 @@ require "rexml/child"
|
||||||
|
|
||||||
module REXML
|
module REXML
|
||||||
##
|
##
|
||||||
# Represents an XML comment; that is, text between <!-- ... -->
|
# Represents an XML comment; that is, text between \<!-- ... -->
|
||||||
class Comment < Child
|
class Comment < Child
|
||||||
include Comparable
|
include Comparable
|
||||||
START = "<!--"
|
START = "<!--"
|
||||||
STOP = "-->"
|
STOP = "-->"
|
||||||
|
|
||||||
attr_accessor :string # The content text
|
# The content text
|
||||||
|
|
||||||
|
attr_accessor :string
|
||||||
|
|
||||||
##
|
##
|
||||||
# Constructor. The first argument can be one of three types:
|
# Constructor. The first argument can be one of three types:
|
||||||
|
|
|
@ -1,17 +1,7 @@
|
||||||
#
|
|
||||||
# = test/unit.rb
|
|
||||||
#
|
|
||||||
# Ruby's standard unit testing library/software.
|
|
||||||
#
|
|
||||||
# Copyright (c) 2000-2003, Nathaniel Talbott.
|
|
||||||
#
|
|
||||||
# See Test::Unit for documentation.
|
|
||||||
#
|
|
||||||
|
|
||||||
require 'test/unit/testcase'
|
require 'test/unit/testcase'
|
||||||
require 'test/unit/autorunner'
|
require 'test/unit/autorunner'
|
||||||
|
|
||||||
module Test
|
module Test # :nodoc:
|
||||||
#
|
#
|
||||||
# = Test::Unit - Ruby Unit Testing Framework
|
# = Test::Unit - Ruby Unit Testing Framework
|
||||||
#
|
#
|
||||||
|
@ -269,11 +259,14 @@ module Test
|
||||||
# practitioners about typos, grammatical errors, unclear statements,
|
# practitioners about typos, grammatical errors, unclear statements,
|
||||||
# missing points, etc., in this document (or any other).
|
# missing points, etc., in this document (or any other).
|
||||||
#
|
#
|
||||||
|
|
||||||
module Unit
|
module Unit
|
||||||
|
# If set to false Test::Unit will not automatically run at exit.
|
||||||
def self.run=(flag)
|
def self.run=(flag)
|
||||||
@run = flag
|
@run = flag
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Automatically run tests at exit?
|
||||||
def self.run?
|
def self.run?
|
||||||
@run ||= false
|
@run ||= false
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#--
|
||||||
|
#
|
||||||
# Author:: Nathaniel Talbott.
|
# Author:: Nathaniel Talbott.
|
||||||
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
|
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
|
||||||
# License:: Ruby license.
|
# License:: Ruby license.
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#--
|
||||||
|
#
|
||||||
# Author:: Nathaniel Talbott.
|
# Author:: Nathaniel Talbott.
|
||||||
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
|
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
|
||||||
# License:: Ruby license.
|
# License:: Ruby license.
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#--
|
||||||
|
#
|
||||||
# Author:: Nathaniel Talbott.
|
# Author:: Nathaniel Talbott.
|
||||||
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
|
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
|
||||||
# License:: Ruby license.
|
# License:: Ruby license.
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#--
|
||||||
|
#
|
||||||
# Author:: Nathaniel Talbott.
|
# Author:: Nathaniel Talbott.
|
||||||
# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.
|
# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.
|
||||||
# License:: Ruby license.
|
# License:: Ruby license.
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#--
|
||||||
# Author:: Nathaniel Talbott.
|
# Author:: Nathaniel Talbott.
|
||||||
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
|
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
|
||||||
# License:: Ruby license.
|
# License:: Ruby license.
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#--
|
||||||
|
#
|
||||||
# Author:: Nathaniel Talbott.
|
# Author:: Nathaniel Talbott.
|
||||||
# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.
|
# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.
|
||||||
# License:: Ruby license.
|
# License:: Ruby license.
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#--
|
||||||
|
#
|
||||||
# Author:: Nathaniel Talbott.
|
# Author:: Nathaniel Talbott.
|
||||||
# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.
|
# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.
|
||||||
# License:: Ruby license.
|
# License:: Ruby license.
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#--
|
||||||
|
#
|
||||||
# Author:: Nathaniel Talbott.
|
# Author:: Nathaniel Talbott.
|
||||||
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
|
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
|
||||||
# License:: Ruby license.
|
# License:: Ruby license.
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#--
|
||||||
|
#
|
||||||
# Author:: Nathaniel Talbott.
|
# Author:: Nathaniel Talbott.
|
||||||
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
|
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
|
||||||
# License:: Ruby license.
|
# License:: Ruby license.
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#--
|
||||||
|
#
|
||||||
# Author:: Kenta MURATA.
|
# Author:: Kenta MURATA.
|
||||||
# Copyright:: Copyright (c) 2000-2002 Kenta MURATA. All rights reserved.
|
# Copyright:: Copyright (c) 2000-2002 Kenta MURATA. All rights reserved.
|
||||||
# License:: Ruby license.
|
# License:: Ruby license.
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#--
|
||||||
|
#
|
||||||
# Author:: Nathaniel Talbott.
|
# Author:: Nathaniel Talbott.
|
||||||
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
|
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
|
||||||
# License:: Ruby license.
|
# License:: Ruby license.
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#--
|
||||||
|
#
|
||||||
# Author:: Nathaniel Talbott.
|
# Author:: Nathaniel Talbott.
|
||||||
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
|
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
|
||||||
# License:: Ruby license.
|
# License:: Ruby license.
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#--
|
||||||
|
#
|
||||||
# Original Author:: Nathaniel Talbott.
|
# Original Author:: Nathaniel Talbott.
|
||||||
# Author:: Kazuhiro NISHIYAMA.
|
# Author:: Kazuhiro NISHIYAMA.
|
||||||
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
|
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#--
|
||||||
|
#
|
||||||
# Author:: Nathaniel Talbott.
|
# Author:: Nathaniel Talbott.
|
||||||
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
|
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
|
||||||
# License:: Ruby license.
|
# License:: Ruby license.
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#--
|
||||||
|
#
|
||||||
# Author:: Nathaniel Talbott.
|
# Author:: Nathaniel Talbott.
|
||||||
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
|
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
|
||||||
# License:: Ruby license.
|
# License:: Ruby license.
|
||||||
|
|
133
lib/tsort.rb
133
lib/tsort.rb
|
@ -8,10 +8,11 @@
|
||||||
# TSort implements topological sorting using Tarjan's algorithm for
|
# TSort implements topological sorting using Tarjan's algorithm for
|
||||||
# strongly connected components.
|
# strongly connected components.
|
||||||
#
|
#
|
||||||
# TSort is designed to be able to be used with any object which can be interpreted
|
# TSort is designed to be able to be used with any object which can be
|
||||||
# as a directed graph.
|
# interpreted as a directed graph.
|
||||||
# TSort requires two methods to interpret an object as a graph:
|
#
|
||||||
# tsort_each_node and tsort_each_child:
|
# TSort requires two methods to interpret an object as a graph,
|
||||||
|
# tsort_each_node and tsort_each_child.
|
||||||
#
|
#
|
||||||
# * tsort_each_node is used to iterate for all nodes over a graph.
|
# * tsort_each_node is used to iterate for all nodes over a graph.
|
||||||
# * tsort_each_child is used to iterate for child nodes of a given node.
|
# * tsort_each_child is used to iterate for child nodes of a given node.
|
||||||
|
@ -30,82 +31,82 @@
|
||||||
# method, which fetches the array of child nodes and then iterates over that
|
# method, which fetches the array of child nodes and then iterates over that
|
||||||
# array using the user-supplied block.
|
# array using the user-supplied block.
|
||||||
#
|
#
|
||||||
# require 'tsort'
|
# require 'tsort'
|
||||||
#
|
#
|
||||||
# class Hash
|
# class Hash
|
||||||
# include TSort
|
# include TSort
|
||||||
# alias tsort_each_node each_key
|
# alias tsort_each_node each_key
|
||||||
# def tsort_each_child(node, &block)
|
# def tsort_each_child(node, &block)
|
||||||
# fetch(node).each(&block)
|
# fetch(node).each(&block)
|
||||||
# end
|
# end
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# {1=>[2, 3], 2=>[3], 3=>[], 4=>[]}.tsort
|
# {1=>[2, 3], 2=>[3], 3=>[], 4=>[]}.tsort
|
||||||
# #=> [3, 2, 1, 4]
|
# #=> [3, 2, 1, 4]
|
||||||
#
|
#
|
||||||
# {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}.strongly_connected_components
|
# {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}.strongly_connected_components
|
||||||
# #=> [[4], [2, 3], [1]]
|
# #=> [[4], [2, 3], [1]]
|
||||||
#
|
#
|
||||||
# == A More Realistic Example
|
# == A More Realistic Example
|
||||||
#
|
#
|
||||||
# A very simple `make' like tool can be implemented as follows:
|
# A very simple `make' like tool can be implemented as follows:
|
||||||
#
|
#
|
||||||
# require 'tsort'
|
# require 'tsort'
|
||||||
#
|
#
|
||||||
# class Make
|
# class Make
|
||||||
# def initialize
|
# def initialize
|
||||||
# @dep = {}
|
# @dep = {}
|
||||||
# @dep.default = []
|
# @dep.default = []
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# def rule(outputs, inputs=[], &block)
|
# def rule(outputs, inputs=[], &block)
|
||||||
# triple = [outputs, inputs, block]
|
# triple = [outputs, inputs, block]
|
||||||
# outputs.each {|f| @dep[f] = [triple]}
|
# outputs.each {|f| @dep[f] = [triple]}
|
||||||
# @dep[triple] = inputs
|
# @dep[triple] = inputs
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# def build(target)
|
# def build(target)
|
||||||
# each_strongly_connected_component_from(target) {|ns|
|
# each_strongly_connected_component_from(target) {|ns|
|
||||||
# if ns.length != 1
|
# if ns.length != 1
|
||||||
# fs = ns.delete_if {|n| Array === n}
|
# fs = ns.delete_if {|n| Array === n}
|
||||||
# raise TSort::Cyclic.new("cyclic dependencies: #{fs.join ', '}")
|
# raise TSort::Cyclic.new("cyclic dependencies: #{fs.join ', '}")
|
||||||
# end
|
# end
|
||||||
# n = ns.first
|
# n = ns.first
|
||||||
# if Array === n
|
# if Array === n
|
||||||
# outputs, inputs, block = n
|
# outputs, inputs, block = n
|
||||||
# inputs_time = inputs.map {|f| File.mtime f}.max
|
# inputs_time = inputs.map {|f| File.mtime f}.max
|
||||||
# begin
|
# begin
|
||||||
# outputs_time = outputs.map {|f| File.mtime f}.min
|
# outputs_time = outputs.map {|f| File.mtime f}.min
|
||||||
# rescue Errno::ENOENT
|
# rescue Errno::ENOENT
|
||||||
# outputs_time = nil
|
# outputs_time = nil
|
||||||
# end
|
# end
|
||||||
# if outputs_time == nil ||
|
# if outputs_time == nil ||
|
||||||
# inputs_time != nil && outputs_time <= inputs_time
|
# inputs_time != nil && outputs_time <= inputs_time
|
||||||
# sleep 1 if inputs_time != nil && inputs_time.to_i == Time.now.to_i
|
# sleep 1 if inputs_time != nil && inputs_time.to_i == Time.now.to_i
|
||||||
# block.call
|
# block.call
|
||||||
# end
|
# end
|
||||||
# end
|
# end
|
||||||
# }
|
# }
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# def tsort_each_child(node, &block)
|
# def tsort_each_child(node, &block)
|
||||||
# @dep[node].each(&block)
|
# @dep[node].each(&block)
|
||||||
# end
|
# end
|
||||||
# include TSort
|
# include TSort
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# def command(arg)
|
# def command(arg)
|
||||||
# print arg, "\n"
|
# print arg, "\n"
|
||||||
# system arg
|
# system arg
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# m = Make.new
|
# m = Make.new
|
||||||
# m.rule(%w[t1]) { command 'date > t1' }
|
# m.rule(%w[t1]) { command 'date > t1' }
|
||||||
# m.rule(%w[t2]) { command 'date > t2' }
|
# m.rule(%w[t2]) { command 'date > t2' }
|
||||||
# m.rule(%w[t3]) { command 'date > t3' }
|
# m.rule(%w[t3]) { command 'date > t3' }
|
||||||
# m.rule(%w[t4], %w[t1 t3]) { command 'cat t1 t3 > t4' }
|
# m.rule(%w[t4], %w[t1 t3]) { command 'cat t1 t3 > t4' }
|
||||||
# m.rule(%w[t5], %w[t4 t2]) { command 'cat t4 t2 > t5' }
|
# m.rule(%w[t5], %w[t4 t2]) { command 'cat t4 t2 > t5' }
|
||||||
# m.build('t5')
|
# m.build('t5')
|
||||||
#
|
#
|
||||||
# == Bugs
|
# == Bugs
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
|
|
||||||
require "delegate"
|
require "delegate"
|
||||||
|
|
||||||
# Weak Reference class that does not bother GCing. This allows the
|
# WeakRef is a class to represent a reference to an object that is not seen by
|
||||||
# referenced object to be garbage collected as if nothing else is
|
# the tracing phase of the garbage collector. This allows the referenced
|
||||||
# referring to it. Because Weakref inherits from Delegator it passes
|
# object to be garbage collected as if nothing is referring to it. Because
|
||||||
# method calls to the object from which it was constructed, so it
|
# WeakRef delegates method calls to the referenced object, it may be used in
|
||||||
# is of the same Duck Type.
|
# place of that object, i.e. it is of the same duck type.
|
||||||
#
|
#
|
||||||
# Usage:
|
# Usage:
|
||||||
|
#
|
||||||
# foo = Object.new
|
# foo = Object.new
|
||||||
# foo = Object.new
|
# foo = Object.new
|
||||||
# p foo.to_s # original's class
|
# p foo.to_s # original's class
|
||||||
|
@ -62,9 +62,9 @@ class WeakRef<Delegator
|
||||||
@@id_rev_map[self.__id__] = @__id
|
@@id_rev_map[self.__id__] = @__id
|
||||||
end
|
end
|
||||||
|
|
||||||
# Return the object this WeakRef references. Raise
|
# Return the object this WeakRef references. Raises RefError if the object
|
||||||
# RefError if this is impossible. The object is that
|
# has been garbage collected. The object returned is the object to which
|
||||||
# to which method calls are delegated (see Delegator).
|
# method calls are delegated (see Delegator).
|
||||||
def __getobj__
|
def __getobj__
|
||||||
unless @@id_rev_map[self.__id__] == @__id
|
unless @@id_rev_map[self.__id__] == @__id
|
||||||
raise RefError, "Illegal Reference - probably recycled", caller(2)
|
raise RefError, "Illegal Reference - probably recycled", caller(2)
|
||||||
|
@ -76,7 +76,8 @@ class WeakRef<Delegator
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Determine if this Weakref still refers to anything.
|
# Returns true if the referenced object still exists, and false if it has
|
||||||
|
# been garbage collected.
|
||||||
def weakref_alive?
|
def weakref_alive?
|
||||||
@@id_rev_map[self.__id__] == @__id
|
@@id_rev_map[self.__id__] == @__id
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue