1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Documentation cleanup.

Includes patches by Hugh Sasse:
* ping.rb
* weakref.rb
* mailread.rb


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@10668 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
drbrain 2006-08-04 18:05:50 +00:00
parent 4db2df633c
commit 52c034aecb
34 changed files with 334 additions and 321 deletions

View file

@ -1,44 +1,51 @@
#
#--
# finalizer.rb -
# $Release Version: 0.3$
# $Revision: 1.4 $
# $Date: 1998/02/27 05:34:33 $
# by Keiju ISHITSUKA
#++
#
# --
#
# Usage:
# Usage:
#
# add dependency R_method(obj, dependant)
# add(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_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_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.
#
# safe{..}
# 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{..}
#
module Finalizer

View file

@ -11,25 +11,22 @@
#
# == Description
#
# +ftools+ adds several (class, not instance) methods to the File class, for copying, moving,
# deleting, installing, and comparing files, as well as creating a directory path. See the
# File class for details.
# ftools adds several (class, not instance) methods to the File class, for
# copying, moving, deleting, installing, and comparing files, as well as
# 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
# option over +ftools+.
#
# FileUtils contains all or nearly all the same functionality and more, and
# is a recommended option over ftools
#
# When you
#
# require 'ftools'
#
# then the File class aquires some utility methods for copying, moving, and deleting files, and
# more.
# then the File class aquires some utility methods for copying, moving, and
# deleting files, and more.
#
# See the method descriptions below, and consider using +fileutils+ as it is more
# comprehensive.
# See the method descriptions below, and consider using FileUtils as it is
# more comprehensive.
#
class File
end
@ -96,8 +93,8 @@ class << File
#
# 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>
# is printed.
# copies from +from+ to <tt>to/from</tt>. If +verbose+ is true, <tt>from ->
# to</tt> is printed.
#
def move(from, to, verbose = false)
to = catname(from, to)
@ -127,7 +124,7 @@ class << File
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.
#
def compare(from, to, verbose = false)

View file

@ -19,6 +19,7 @@ warn "Warning:#{caller[0].sub(/:in `.*'\z/, '')}: getopts is deprecated after Ru
$RCS_ID=%q$Header$
# getopts is obsolete. Use GetoptLong.
def getopts(single_options, *options)
boolopts = {}

View file

@ -12,21 +12,23 @@ require "socket"
require "thread"
#
# +GServer+ implements a generic server, featuring thread pool management, simple logging, and
# multi-server management. See <tt>xmlrpc/httpserver.rb</tt> in the Ruby standard library for
# an example of +GServer+ in action.
# GServer implements a generic server, featuring thread pool management,
# simple logging, and multi-server management. See HttpServer in
# <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
# multiple simultaneous connections from clients, up to an optional maximum number. Several
# _services_ (i.e. one service per TCP port) can be run simultaneously, and stopped at any time
# through the class method <tt>GServer.stop(port)</tt>. All the threading issues are handled,
# saving you the effort. All events are optionally logged, but you can provide your own event
# handlers if you wish.
# Any kind of application-level server can be implemented using this class.
# It accepts multiple simultaneous connections from clients, up to an optional
# maximum number. Several _services_ (i.e. one service per TCP port) can be
# run simultaneously, and stopped at any time through the class method
# <tt>GServer.stop(port)</tt>. All the threading issues are handled, saving
# you the effort. All events are optionally logged, but you can provide your
# own event handlers if you wish.
#
# === Example
#
# Using +GServer+ is simple. Below we implement a simple time server, run it, query it, and
# shut it down. Try this code in +irb+:
# Using GServer is simple. Below we implement a simple time server, run it,
# query it, and shut it down. Try this code in +irb+:
#
# require 'gserver'
#
@ -60,14 +62,16 @@ require "thread"
# GServer.stop(10001)
# # or, of course, "server.stop".
#
# All the business of accepting connections and exception handling is taken care of. All we
# have to do is implement the method that actually serves the client.
# All the business of accepting connections and exception handling is taken
# care of. All we have to do is implement the method that actually serves the
# client.
#
# === Advanced
#
# As the example above shows, the way to use +GServer+ is to subclass it to create a specific
# server, overriding the +serve+ method. You can override other methods as well if you wish,
# perhaps to collect statistics, or emit more detailed logging.
# As the example above shows, the way to use GServer is to subclass it to
# create a specific server, overriding the +serve+ method. You can override
# other methods as well if you wish, perhaps to collect statistics, or emit
# more detailed logging.
#
# connecting
# disconnecting
@ -76,8 +80,8 @@ require "thread"
#
# 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
# logging system.
# You can also override +log+ and +error+ if, for example, you wish to use a
# more sophisticated logging system.
#
class GServer

View file

@ -14,21 +14,21 @@
#
#== 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 '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'

View file

@ -1,9 +1,8 @@
# logger.rb - saimple logging utility
# Copyright (C) 2000-2003, 2005 NAKAMURA, Hiroshi <nakahiro@sarion.co.jp>.
require 'monitor'
# = logger.rb
#
# Simple logging utility.
#
# 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
# license; either the dual license version in 2003, or any later version.
# Revision:: $Id$
#
# See Logger for documentation.
#
require 'monitor'
#
# == Description
#

View file

@ -1,5 +1,14 @@
# The Mail class represents an internet mail message (as per RFC822, RFC2822)
# with headers and a body.
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)
unless defined? f.gets
f = open(f, "r")
@ -34,14 +43,19 @@ class Mail
end
end
# Return the headers as a Hash.
def header
return @header
end
# Return the message body as an Array of lines
def body
return @body
end
# Return the header corresponding to +field+.
#
# Matching is case-insensitive.
def [](field)
@header[field.capitalize]
end

View file

@ -1,4 +1,4 @@
#
#--
# mutex_m.rb -
# $Release Version: 3.0$
# $Revision: 1.7 $
@ -7,22 +7,26 @@
# by Keiju ISHITSUKA(keiju@ishitsuka.com)
# modified by matz
# patched by akira yamada
#++
#
# --
# 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
# == Usage
#
# 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
def Mutex_m.define_aliases(cl)

View file

@ -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 'stringio'
require 'time'
@ -91,6 +35,59 @@ module Kernel
module_function :open
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
Options = {
:proxy => true,

View file

@ -3,19 +3,24 @@
# which IO#popen does not allow)
#
# Usage:
# require "open3"
#
# stdin, stdout, stderr = Open3.popen3('nroff -man')
# or
# include Open3
# stdin, stdout, stderr = popen3('nroff -man')
# require "open3"
#
# stdin, stdout, stderr = Open3.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.
# or:
#
# Such as
# Open3.popen3('nroff -man') { |stdin, stdout, stderr| ... }
# 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
#[stdin, stdout, stderr] = popen3(command);

View file

@ -25,24 +25,22 @@
#
# === Object relationship diagram
#
# +--------------+
# | OptionParser |<>-----+
# +--------------+ | +--------+
# | ,-| Switch |
# on_head -------->+---------------+ / +--------+
# accept/reject -->| List |<|>-
# | |<|>- +----------+
# on ------------->+---------------+ `-| argument |
# : : | class |
# +---------------+ |==========|
# on_tail -------->| | |pattern |
# +---------------+ |----------|
# OptionParser.accept ->| DefaultList | |converter |
# reject |(shared between| +----------+
# | all instances)|
# +---------------+
# +--------------+
# | OptionParser |<>-----+
# +--------------+ | +--------+
# | ,-| Switch |
# on_head -------->+---------------+ / +--------+
# accept/reject -->| List |<|>-
# | |<|>- +----------+
# on ------------->+---------------+ `-| argument |
# : : | class |
# +---------------+ |==========|
# on_tail -------->| | |pattern |
# +---------------+ |----------|
# OptionParser.accept ->| DefaultList | |converter |
# reject |(shared between| +----------+
# | all instances)|
# +---------------+
#
# == OptionParser
#

View file

@ -57,6 +57,8 @@ def setExpression(ex, opt, op)
return ex
end
# parseArgs is obsolete. Use OptionParser instead.
def parseArgs(argc, nopt, single_opts, *opts)
if (noOptions = getopts(single_opts, *opts)) == nil
printUsageAndExit()

View file

@ -1,46 +1,35 @@
#
# ping.rb -- check a host for upness
#
require 'timeout'
require "socket"
#= SYNOPSIS
#
# 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
#
# This module contains routines to test for the reachability of remote hosts.
# 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
# host is available to rsh(1), ftp(1), or telnet(1) onto.
#
#== 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".
# host is available to rsh(1), ftp(1), or telnet(1) to.
#
#= WARNING
#
# pingecho() uses user-level thread to implement the timeout, so it may block
# for long period if named does not respond for some reason.
# pingecho() may block for a long period if name resolution is slow. Require
# 'resolv-replace' to use non-blocking name resolution.
#
#=end
require 'timeout'
require "socket"
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")
begin
timeout(timeout) do

View file

@ -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
in the README file of the Ruby distribution.
----
= Usage
RDoc is invoked from the command line using:

View file

@ -21,6 +21,8 @@ require 'ftools'
# clutter.
#
# ToDo: This isn't universally true.
#
# :include: README
module RDoc

View file

@ -1,22 +1,22 @@
# readbytes.rb
#
# add IO#readbytes, which reads fixed sized data.
# it guarantees read data size.
# TruncatedDataError is raised when IO#readbytes fails to read enough data.
class TruncatedDataError<IOError
def initialize(mesg, data)
def initialize(mesg, data) # :nodoc:
@data = data
super(mesg)
end
# The read portion of an IO#readbytes attempt.
attr_reader :data
end
class IO
# reads exactly n bytes from the IO stream.
# If the data read is nil, raises EOFError.
# If the data read is too short, raises TruncatedDataError.
# The method TruncatedDataError#data may be used to obtain
# the truncated message.
# Reads exactly +n+ bytes.
#
# If the data read is nil an EOFError is raised.
#
# If the data read is too short a TruncatedDataError is raised and the read
# data is obtainable via its #data method.
def readbytes(n)
str = read(n)
if str == nil

View file

@ -2,13 +2,15 @@ require "rexml/child"
module REXML
##
# Represents an XML comment; that is, text between <!-- ... -->
# Represents an XML comment; that is, text between \<!-- ... -->
class Comment < Child
include Comparable
START = "<!--"
STOP = "-->"
attr_accessor :string # The content text
# The content text
attr_accessor :string
##
# Constructor. The first argument can be one of three types:

View file

@ -1,4 +1,4 @@
# :nodoc:
#--
#
# Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.

View file

@ -1,4 +1,4 @@
# :nodoc:
#--
#
# Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.

View file

@ -1,4 +1,4 @@
# :nodoc:
#--
#
# Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.

View file

@ -1,4 +1,4 @@
# :nodoc:
#--
#
# Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.

View file

@ -1,4 +1,4 @@
# :nodoc:
#--
#
# Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.

View file

@ -1,4 +1,4 @@
# :nodoc:
#--
#
# Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.

View file

@ -1,4 +1,4 @@
# :nodoc:
#--
#
# Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.

View file

@ -1,4 +1,4 @@
# :nodoc:
#--
#
# Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.

View file

@ -1,4 +1,4 @@
# :nodoc:
#--
#
# Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.

View file

@ -1,4 +1,4 @@
# :nodoc:
#--
#
# Author:: Kenta MURATA.
# Copyright:: Copyright (c) 2000-2002 Kenta MURATA. All rights reserved.

View file

@ -1,4 +1,4 @@
# :nodoc:
#--
#
# Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.

View file

@ -1,4 +1,4 @@
# :nodoc:
#--
#
# Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.

View file

@ -1,4 +1,4 @@
# :nodoc:
#--
#
# Original Author:: Nathaniel Talbott.
# Author:: Kazuhiro NISHIYAMA.

View file

@ -1,4 +1,4 @@
# :nodoc:
#--
#
# Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.

View file

@ -1,4 +1,4 @@
# :nodoc:
#--
#
# Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.

View file

@ -8,10 +8,11 @@
# TSort implements topological sorting using Tarjan's algorithm for
# strongly connected components.
#
# TSort is designed to be able to be used with any object which can be interpreted
# as a directed graph.
# TSort requires two methods to interpret an object as a graph:
# tsort_each_node and tsort_each_child:
# TSort is designed to be able to be used with any object which can be
# interpreted as a directed graph.
#
# 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_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
# array using the user-supplied block.
#
# require 'tsort'
#
# class Hash
# include TSort
# alias tsort_each_node each_key
# def tsort_each_child(node, &block)
# fetch(node).each(&block)
# end
# end
#
# {1=>[2, 3], 2=>[3], 3=>[], 4=>[]}.tsort
# #=> [3, 2, 1, 4]
#
# {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}.strongly_connected_components
# #=> [[4], [2, 3], [1]]
# require 'tsort'
#
# class Hash
# include TSort
# alias tsort_each_node each_key
# def tsort_each_child(node, &block)
# fetch(node).each(&block)
# end
# end
#
# {1=>[2, 3], 2=>[3], 3=>[], 4=>[]}.tsort
# #=> [3, 2, 1, 4]
#
# {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}.strongly_connected_components
# #=> [[4], [2, 3], [1]]
#
# == A More Realistic Example
#
# A very simple `make' like tool can be implemented as follows:
#
# require 'tsort'
#
# class Make
# def initialize
# @dep = {}
# @dep.default = []
# end
#
# def rule(outputs, inputs=[], &block)
# triple = [outputs, inputs, block]
# outputs.each {|f| @dep[f] = [triple]}
# @dep[triple] = inputs
# end
#
# def build(target)
# each_strongly_connected_component_from(target) {|ns|
# if ns.length != 1
# fs = ns.delete_if {|n| Array === n}
# raise TSort::Cyclic.new("cyclic dependencies: #{fs.join ', '}")
# end
# n = ns.first
# if Array === n
# outputs, inputs, block = n
# inputs_time = inputs.map {|f| File.mtime f}.max
# begin
# outputs_time = outputs.map {|f| File.mtime f}.min
# rescue Errno::ENOENT
# outputs_time = nil
# end
# if outputs_time == nil ||
# inputs_time != nil && outputs_time <= inputs_time
# sleep 1 if inputs_time != nil && inputs_time.to_i == Time.now.to_i
# block.call
# end
# end
# }
# end
#
# def tsort_each_child(node, &block)
# @dep[node].each(&block)
# end
# include TSort
# end
#
# def command(arg)
# print arg, "\n"
# system arg
# end
#
# m = Make.new
# m.rule(%w[t1]) { command 'date > t1' }
# m.rule(%w[t2]) { command 'date > t2' }
# m.rule(%w[t3]) { command 'date > t3' }
# 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.build('t5')
# require 'tsort'
#
# class Make
# def initialize
# @dep = {}
# @dep.default = []
# end
#
# def rule(outputs, inputs=[], &block)
# triple = [outputs, inputs, block]
# outputs.each {|f| @dep[f] = [triple]}
# @dep[triple] = inputs
# end
#
# def build(target)
# each_strongly_connected_component_from(target) {|ns|
# if ns.length != 1
# fs = ns.delete_if {|n| Array === n}
# raise TSort::Cyclic.new("cyclic dependencies: #{fs.join ', '}")
# end
# n = ns.first
# if Array === n
# outputs, inputs, block = n
# inputs_time = inputs.map {|f| File.mtime f}.max
# begin
# outputs_time = outputs.map {|f| File.mtime f}.min
# rescue Errno::ENOENT
# outputs_time = nil
# end
# if outputs_time == nil ||
# inputs_time != nil && outputs_time <= inputs_time
# sleep 1 if inputs_time != nil && inputs_time.to_i == Time.now.to_i
# block.call
# end
# end
# }
# end
#
# def tsort_each_child(node, &block)
# @dep[node].each(&block)
# end
# include TSort
# end
#
# def command(arg)
# print arg, "\n"
# system arg
# end
#
# m = Make.new
# m.rule(%w[t1]) { command 'date > t1' }
# m.rule(%w[t2]) { command 'date > t2' }
# m.rule(%w[t3]) { command 'date > t3' }
# 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.build('t5')
#
# == Bugs
#

View file

@ -1,13 +1,13 @@
require "delegate"
# Weak Reference class that does not bother GCing. This allows the
# referenced object to be garbage collected as if nothing else is
# referring to it. Because Weakref inherits from Delegator it passes
# method calls to the object from which it was constructed, so it
# is of the same Duck Type.
# WeakRef is a class to represent a reference to an object that is not seen by
# the tracing phase of the garbage collector. This allows the referenced
# object to be garbage collected as if nothing is referring to it. Because
# WeakRef delegates method calls to the referenced object, it may be used in
# place of that object, i.e. it is of the same duck type.
#
# Usage:
#
# foo = Object.new
# foo = Object.new
# p foo.to_s # original's class
@ -64,9 +64,9 @@ class WeakRef<Delegator
super
end
# Return the object this WeakRef references. Raise
# RefError if this is impossible. The object is that
# to which method calls are delegated (see Delegator).
# Return the object this WeakRef references. Raises RefError if the object
# has been garbage collected. The object returned is the object to which
# method calls are delegated (see Delegator).
def __getobj__
unless @@id_rev_map[self.object_id] == @__id
Kernel::raise RefError, "Illegal Reference - probably recycled", Kernel::caller(2)
@ -77,10 +77,12 @@ class WeakRef<Delegator
Kernel::raise RefError, "Illegal Reference - probably recycled", Kernel::caller(2)
end
end
def __setobj__(obj)
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?
@@id_rev_map[self.object_id] == @__id
end