Programming Ruby
The Pragmatic Programmer's Guide
Standard Library
Ruby comes ``out of the box'' with a large and useful library of
modules and classes. This chapter contains a sampling of the more
useful of these.
Interestingly, and unlike some of the code in later chapters, all of
these libraries are written in Ruby. You'll find the source in the
lib subdirectory of the standard Ruby distribution.
class Complex
Parent:
Numeric
Version:
1.6
Index:
new
Arithmetic operations
<=>
==
abs
abs2
arg
conjugate
image
polar
real
to_f
to_i
to_r
to_s
require "complex"
v1 = Complex(2,3)
サ
Complex(2, 3)
v2 = 2.im
サ
Complex(0, 2)
v1 + v2
サ
Complex(2, 5)
v1 * v2
サ
Complex(-6, 4)
v2**2
サ
Complex(-4, 0)
Math.sin(v1)
サ
Complex(9.154499147, -4.16890696)
v1 < v2
サ
false
v2**2 == -4
サ
true
constants
class methods
new
Complex.new(
a,
b )
->
aComplex
Returns a + b
i.
In addition to the
Complex.new constructor, the
Complex
library defines the method
Numeric.im
, such that
aNumeric
.im returns 0 +
aNumeric
i. Complex
numbers are also constructed using the global method
Complex, which takes one or two arguments. The value it
returns depends on the type of its arguments:
a
b
Result
Number
Number
a + bi
Complex
0
a
Complex
Complex
Complex( a.real - b.image,
a.image + b.real )
Number
Complex
Complex( a - b.image,
b.real )
instance methods
Performs various arithmetic operations on
ref.
ref
+
aNumeric
-> aComplex
Addition
ref
-
aNumeric
-> aComplex
Subtraction
ref
*
aNumeric
-> aComplex
Multiplication
ref
/
aNumeric
-> aComplex
Division
ref
%
aNumeric
-> aComplex
Remainder
ref
**
aNumeric
-> aComplex
Exponentiation (real and
complex power)
<=>
ref <=>
other -> -1, 0, +1
Returns
ref.abs
<=> other.abs.
==
ref ==
anObject ->
true or
false
If
anObject is a complex number, returns
true if
its real and imaginary parts match
ref. If
anObject is a
simple number, returns
true if
ref.
real equals
anObject and
ref.
image is zero. Otherwise, attempts to
coerce
anObject to a complex number and compares the result.
Absolute value.
Square of absolute value.
Argument (angle from (1,0)).
Complex conjugate.
image
ref.image ->
aNumeric
The imaginary part of
ref.
polar
ref.polar ->
anArray
Returns the two-element array: [
c.abs,
c.arg].
real
ref.real ->
aNumeric
The real part of
ref.
to_f
ref.to_f ->
aComplex
Returns
Complex(real.to_f, image.to_f).
to_i
ref.to_i ->
aComplex
Returns
Complex(real.to_i, image.to_i).
to_r
ref.to_r ->
aComplex
Returns
Complex(real.to_r, image.to_r), converting both
parts of the complex to a rational number.
String representation of
ref.
In addition, the
Math functions
sqrt,
exp,
cos,
sin,
tan,
log,
log10, and
atan2 are
extended to support a
Complex argument.
class Date
Parent:
Object
Version:
1.6
Index:
exist2?
exist?
existw?
gregorian_leap?
julian_leap?
leap?
new
new1
new2
new3
neww
today
Accessors
+
--
<<
<=>
===
>>
downto
england
gregorian
italy
jd
julian
leap?
mjd
newsg
next
ns?
os?
sg
step
succ
to_s
upto
require 'date'
d = Date.new(2000, 3, 31)
サ
#<Date: 2451635,2299161>
[d.year, d.yday, d.wday]
サ
[2000, 91, 5]
[d.month, d.mday]
サ
[3, 31]
[d.cwyear, d.cweek, d.cwday]
サ
[2000, 13, 5]
[d.jd, d.mjd]
サ
[2451635, 51634.5]
(d << 1).to_s
サ
"2000-02-29"
d.succ.to_s
サ
"2000-04-01"
(d + 100).to_s
サ
"2000-07-09"
d.leap?
サ
true
Date.new(2000, 3, -10).to_s
サ
"2000-03-22"
d1 = Date.neww(2000, 13, 7)
サ
#<Date: 2451637,2299161>
d1.to_s
サ
"2000-04-02"
[d1.cwday, d1.wday]
サ
[7, 0]
The
date library implements class
Date, which provides a
comprehensive set of facilities for storing, manipulating, and
converting dates. To document its options, we need to take a brief
historical detour to establish some vocabulary.
Internally a date is stored as a Julian day number, the number of
days since midday, January 1st, 4713 BCE.
[In
the code, you may find references to the year -4712. As astronomical
dates include a year zero, 4713 BCE is the same year as
-4712.] The rules for converting a Julian day number to a
calendar date are complicated because the Romans estimated the
length of a year incorrectly. In the Julian calendar (often called
Old Style, or O.S.), every year divisible by 4 is a leap year.
The
Date class has options to convert dates using this as an
assumption.
By the sixteenth century, the inaccuracies in this measurement had
become apparent. An edict from Pope Gregory XIII in 1582 created the
New Style (N.S.) or Gregorian calendar, where years divisible by 100 were no
longer leap years unless they were also divisible by 400. This system was
adopted by most Catholic countries immediately, but religious
differences held up a wider adoption. England (and several other
countries) switched in 1752, with some countries following later.
The
Date class allows you to determine whether to implement the
cutover in 1582 (the
Date::ITALY option), 1752
(
Date::ENGLAND), or another date of your choosing.
The
Date class also provides conversions to Modified Julian Day
(MJD) numbers.
MJD values count from midnight, November 17, 1858. Because these
values count from midnight, not midday, there is a half-day added to the
conversion factor.
The descriptions that follow use the abbreviations listed
in Table 24.1 on page 441.
Abbreviations used describing dates
Field
Meaning
cwday
An ISO 8601 calendar weekday. 1 is Monday, 7 is Sunday.
cweek
An ISO 8601 calendar week. Week 1 is the week containing the
first Thursday (or equivalently the week that contains
January 4th).
cwyear
An ISO 8601 calendar-week-based year. May be different from
year, as it rolls forward only on a Monday.
jd
The Julian day number---the number of days since January
1st, 4713 BCE.
mday
The day of the month (1..31).
mjd
A modified Julian day number.
mon
The month of the year (1..12).
sg
The start of the Gregorian correction: Date::ITALY (the
default) for 1582, Date::ENGLAND for 1752, or
JULIAN, meaning no correction. You may also provide an
arbitrary Julian day number for this parameter, in which case the
correction will start from this date.
wday
The day of the week (0 is Sunday).
week
The week number into a year (1..53).
yday
The day into the year (1..366).
year
A year (1966, 2001, and the like).
Class
Date exports the constant arrays
Date::MONTHNAMES
and
Date::DAYNAMES, which can be indexed by
mon and
wday values to return the corresponding English names.
The
Date class also provides low-level date-conversion methods:
* civil_to_jd
* jd_to_civil
* commercial_to_jd
* jd_to_commercial
* ordinal_to_jd
* jd_to_ordinal
* jd_to_mjd
* mjd_to_jd
These methods perform limited error checking of their parameters, and are not
documented here. The somewhat confusingly named
exist..?
routines perform conversions from different formats into a Julian day
number with error checking. These routines also automatically
normalize their parameters.
mixins
Comparable:
<, <=, ==, >=, >, between?
class methods
exist2?
Date.exist2?(
year,
yday,
sg=
Date::ITALY) ->
jd
Converts a
year and
yday into a Julian day number,
returning
nil on error.
exist?
Date.exist?(
year,
mon,
mday,
sg=
Date::ITALY) ->
jd
Converts a
year,
mon, and
mday into a Julian day
number, or
nil if the parameters are invalid.
existw?
Date.existw?(
cyear,
cweek,
cwday,
sg=
Date::ITALY)
->
jd
Converts a
cyear,
cweek, and
cwday into a Julian day number.
If
year does not end with ``00'', returns
true if
year is divisible by 4, otherwise returns
true
if
year is divisible by 400.
Returns
true if
year is divisible by 4.
leap?
Date.leap?(
year ) ->
true or
false
Synonym for
Date.gregorian_leap?.
new
Date.new(
year=-4712,
mon=1,
mday=1,
sg=
Date::ITALY) ->
aNewDate
Returns a
Date for the given
year,
mon, and
mday. If
mon is negative, it counts back from the end of the
year. If
mday is negative, it counts back from the
end of the month.
new1
Date.new1(
jd,
sg=
Date::ITALY)
->
aNewDate
Creates a
Date corresponding to the given Julian day
number.
new2
Date.new2(
year=-4712,
yday=1,
sg=
Date::ITALY) ->
aNewDate
Returns a
Date for the given
year and
yday. If
yday is negative, it counts back from the
end of the year.
new3
Date.new3(
year=-4712,
mon=1,
mday=1,
sg=
Date::ITALY) ->
aNewDate
Synonym for
Date.new.
neww
Date.neww(
cyear=1582,
cweek=41,
cwday=5,
sg=
Date::ITALY) ->
aNewDate
Returns
a
Date for the given
cyear,
cweek, and
cwday. If
cweek is negative, it counts back from the end
of the year. If
cwday is negative, it counts back
from the end of the week.
today
Date.today(
sg=
Date::ITALY)
->
aNewDate
Returns a
Date for today.
instance methods
Accessors
ref.year ->
year
ref.yday ->
yday
ref.mjd ->
mjd
ref.mon ->
mon
ref.month ->
mon
ref.mday ->
mday
ref.day ->
mday
ref.cwyear ->
cwyear
ref.cweek ->
cweek
ref.cwday ->
cwday
ref.wday ->
wday
Returns the given component of
ref as a number.
+
ref +
anInteger
->
aNewDate
Returns a new
Date anInteger days from
ref.
--
ref - anInteger ->
aNewDate
ref - anOtherDate ->
anInteger
The first form returns a new
Date anInteger days
before
ref.
The second form
returns the number of days between
ref and
anOtherDate.
<<
ref <<
anInteger ->
aNewDate
Returns a new
Date formed by subtracting
anInteger months to
ref,
adjusting the
mday value back to the last day of the month if it
otherwise exceeds it.
<=>
ref <=>
anOther -> -1, 0, +1
anOther must be a
Numeric, in which case it is
treated as
a Julian day number, or a
Date.
Returns -1, 0, +1 if
ref is
less than, equal to, or greater than
anOther. See module
Comparable on page 402.
===
ref ===
anOther ->
true or
false
anOther must be a
Numeric, in which case it is
treated as
a Julian day number, or a
Date.
Returns
true if the
Julian day number of
anOther is the same as
ref.
>>
ref >>
anInteger ->
aNewDate
Returns a new
Date formed by adding
anInteger months to
ref,
adjusting the
mday value back to the last day of the month if it
otherwise exceeds it.
downto
ref.downto(
aDateMin )
{| date | block }
->
ref
Invokes block with dates from
ref down to
aDateMin.
Equivalent to
ref
.newsg(Date::ENGLAND).
Equivalent to
ref
.newsg(Date::GREGORIAN).
Equivalent to
ref
.newsg(Date::ITALY).
Returns the Julian day number for
ref.
Equivalent to
ref
.newsg(Date::JULIAN).
leap?
ref.leap? ->
true or
false
Returns
true if
ref falls within a leap year.
Returns the Julian day number of
ref converted to a modified Julian
day number.
newsg
ref.newsg(
sg=
Date::ITALY )
->
aNewDate
Returns a new
Date.
next
ref.next ->
aNewDate
Synonym for
ref.succ.
ns?
ref.ns? ->
true or
false
Returns
true if
ref falls in the period of New Style dates.
os?
ref.os? ->
true or
false
Returns
true if
ref falls in the period of Old Style dates.
Returns the Julian day number of the start of New Style dates for
ref.
step
ref.step(
aDateLimit,
step )
{| date | block }
->
ref
Invokes block with dates starting at
ref,
incrementing by
step days, ending at the first date greater than
aDateLimit (less than for a negative step).
succ
ref.succ ->
aNewDate
Returns the date of
ref plus one day.
Returns
self as ``year-mon-mday.''
upto
ref.upto(
aDateMax )
{| date | block }
->
ref
Invokes block with dates from
ref to
aDateMax.
Library: English
require "English"
$OUTPUT_FIELD_SEPARATOR = ' -- '
"waterbuffalo" =~ /buff/
print $LOADED_FEATURES, $POSTMATCH, $PID, "\n"
print $", $', $,ドル "\n"
produces:
English.rb -- alo -- 32130 --
English.rb -- alo -- 32130 --
Include the English library file in a Ruby script, and you can
reference the global variables such as
$_ using less
cryptic names, listed in the following table.
$*
$ARGV
$"
$LOADED_FEATURES
$?
$CHILD_STATUS
$&
$MATCH
$<
$DEFAULT_INPUT
$.
$NR
$>
$DEFAULT_OUTPUT
,ドル
$OFS
$!
$ERROR_INFO
$\
$ORS
$@
$ERROR_POSITION
$\
$OUTPUT_RECORD_SEPARATOR
$;
$FIELD_SEPARATOR
,ドル
$OUTPUT_FIELD_SEPARATOR
$;
$FS
$$
$PID
$=
$IGNORECASE
$'
$POSTMATCH
$.
$INPUT_LINE_NUMBER
$`
$PREMATCH
$/
$INPUT_RECORD_SEPARATOR
$$
$PROCESS_ID
$~
$LAST_MATCH_INFO
0ドル
$PROGRAM_NAME
$+
$LAST_PAREN_MATCH
$/
$RS
$_
$LAST_READ_LINE
module Find
Index:
find
prune
require "find"
Find.find("/etc/passwd", "/var/spool/lp1", ".") do |f|
Find.prune if f == "."
puts f
end
produces:
/etc/passwd
/var/spool/lp1
/var/spool/lp1/status
/var/spool/lp1/lock
/var/spool/lp1/.seq
The
Find module supports the top-down traversal of a set of
file paths.
class methods
find
ref.find(
[
aName
]*
) {| aFileName | block }
Calls the associated block with the name of every file and
directory listed as arguments, then recursively on their
subdirectories, and so on.
Skips the current file or directory, restarting the
loop with the next entry. If the current file is a directory,
that directory will not be recursively entered.
Meaningful only within the block associated with
Find::find.
class File
Parent:
IO
Version:
1.6
Index:
cmp
compare
copy
cp
install
makedirs
mkpath
move
mv
rm_f
safe_unlink
syscopy
require 'ftools'
File.copy 'testfile', 'testfile1'
サ
true
File.compare 'testfile', 'testfile1'
サ
true
The
FTools library adds several methods to the built-in
File class. These methods are particularly useful to programs
that move and copy files, such as installers.
class methods
cmp
ref.cmp(
name1,
name2,
verbose=
false )
->
true or
false
Synonym for
File.compare
.
compare
ref.compare(
name1,
name2,
verbose=
false )
->
true or
false
Returns
true only if the contents of files
name1
and
name2 are identical.
copy
ref.copy(
fromName,
toName,
verbose=
false )
->
true or
false
Equivalent to calling
File.syscopy
, but logs the attempt to
$stderr if
verbose is not
false.
cp
ref.cp(
fromName,
toName,
verbose=
false )
->
true or
false
Synonym for
File.copy
.
install
ref.install(
fromName,
toName,
aMode=
nil,
verbose=
false )
Copies file
fromName to file
toName using
File.syscopy
, unless
toName already exists and has the
same content as
fromName. Sets the mode of the resulting file
to
aMode unless
aMode is
nil.
makedirs
ref.makedirs(
[
dirName
]*
[,
aBoolean
] )
Creates the given directories, logging each attempt to
$stderr if the last parameter is
true. Creates any missing parent directories as
required.
mkpath
ref.mkpath(
[
dirName
]*
[,
aBoolean
] )
Synonym for
File.makedirs
.
move
ref.move(
fromName,
toName,
verbose=
false )
->
true or
false
Effectively renames
fromName to
toName, logging to
$stderr if
verbose is not
false.
mv
ref.mv(
fromName,
toName,
verbose=
false )
->
true or
false
Synonym for
File.move
.
rm_f
ref.rm_f(
[
fileName
]*
[,
aBoolean
] )
->
anInteger
Synonym for
File.safe_unlink
(the name refers
to the Unix
rm -f command).
safe_unlink
ref.safe_unlink(
[
fileName
]*
[,
aBoolean
] )
->
anInteger or
nil
Unlinks (deletes) the given files, logging to
$stderr if
the last parameter is
true. The method attempts to make all files
writable before unlinking them, so no errors will occur deleting
read-only files. Returns the number of files deleted, or
nil
on error.
syscopy
ref.syscopy(
fromName,
toName )
->
true or
false
Efficiently copies the file named
fromName to
toName. If
toName names a directory, the destination
will be a file in that directory with the same basename as
fromName. After the copy, the file mode of
toName
will be the same as that of
fromName. Returns
true
on success.
class GetoptLong
Parent:
Object
Version:
1.6
Index:
new
each
error?
error_message
get
get_option
ordering
ordering=
quiet
quiet=
quiet?
set_options
terminate
terminated?
# Call using "ruby example.rb --size 10k -v -q a.txt b.doc"
require 'getoptlong'
# specify the options we accept and initialize
# the option parser
opts = GetoptLong.new(
[ "--size", "-s", GetoptLong::REQUIRED_ARGUMENT ],
[ "--verbose", "-v", GetoptLong::NO_ARGUMENT ],
[ "--query", "-q", GetoptLong::NO_ARGUMENT ],
[ "--check", "--valid", "-c", GetoptLong::NO_ARGUMENT ]
)
# process the parsed options
opts.each do |opt, arg|
puts "Option: #{opt}, arg #{arg.inspect}"
end
puts "Remaining args: #{ARGV.join(', ')}"
produces:
Option: --size, arg "10k"
Option: --verbose, arg ""
Option: --query, arg ""
Remaining args: a.txt, b.doc
Class
GetoptLong supports GNU-style command-line option parsing.
Options may be a minus sign (`-') followed by a single character, or
two minus signs (`--') followed by a name (a long option). Long
options may be abbreviated to their shortest unambiguous lengths.
A single internal option may have multiple external representations.
For example, the option to control verbose output could be any of
-v,
--verbose, or
--details. Some options may
also take an associated value.
Each internal option is passed to
GetoptLong as an array,
containing strings representing the option's external forms and a
flag. The flag (
NO_ARGUMENT,
REQUIRED_ARGUMENT, or
OPTIONAL_ARGUMENT) specifies how
GetoptLong is to
associate an argument with the option.
If the environment variable
POSIXLY_CORRECT is set, all options
must precede nonoptions on the command line. Otherwise, the default
behavior of
GetoptLong is to reorganize the command line to put
the options at the front. This behavior may be changed by setting
GetoptLong#ordering= to one of the constants
PERMUTE,
REQUIRE_ORDER, or
RETURN_IN_ORDER.
POSIXLY_CORRECT may not be overridden.
constants
Per-option constants
OPTIONAL_ARGUMENT
A nonoption following this option
will be used as this option's argument.
Overall constants
PERMUTE
Options and their arguments will be shuffled
to the front of the command line.
REQUIRE_ORDER
Options and their arguments must
appear at the start of the command line. The first nonoption
terminates option processing.
RETURN_IN_ORDER
Return options in the order in
which they occur on the command line.
class methods
new
GetoptLong.new(
[
options
]*
) ->
ref
Returns a new option parser. Any
options are passed to
ref.
set_options.
instance methods
each
ref.each {| anOption, anArgument | block }
Loops calling
GetoptLong#get, passing the returned option
and argument to the associated block. The loop ends when
get
returns
nil for
anOption.
error?
ref.error?
->
anException
Returns an
Exception object documenting any error that has
occurred, or
nil if there has not been an error.
Returns the text of the last error message.
get
ref.get -> [
anOption,
anArgument ]
Returns the next option, along with any associated argument. If
there is no argument,
nil is returned for
anArgument. If there are no remaining unprocessed options,
or if there is an error in option processing and
quiet
has been set,
nil is returned for
anOption. Otherwise,
if there is an error, a message is written to
$stderr and
an exception (a subclass of
StandardError) is raised.
The option string returned is the first option that was given in
the corresponding array passed to
set_options.
get_option
ref.get_option -> [
anOption,
anArgument ]
Synonym for
GetoptLong#get.
Returns the current ordering.
Sets the ordering to one of
PERMUTE,
REQUIRE_ORDER,
or
RETURN_IN_ORDER. Quietly ignored if the environment
variable
POSIXLY_CORRECT is set. Ordering may not be
changed once option processing has been started.
quiet
ref.quiet ->
true or
false
Returns the current value of the
quiet attribute.
quiet=
ref.quiet =
true or
false
Sets the current value of the
quiet attribute. If
false, any errors encountered are reported to
$stderr.
quiet?
ref.quiet? ->
true or
false
Synonym for
GetoptLong#quiet.
Each parameter is an array specifying a single internal option.
The array contains one or more strings specifying the external
form(s) of the option, and one of the flags
NO_ARGUMENT,
OPTIONAL_ARGUMENT, or
REQUIRED_ARGUMENT. See the
sample code on page 448 for examples of use.
Terminates option processing. Any remaining arguments are
written back to
ARGV. This may be called from within a
GetoptLong#each or on its own. For example, calling the
following program using ``
ruby example.rb --size 10k -v
-term -q a.txt b.doc'' will leave the
-q and filenames
in
ARGV.
require 'getoptlong'
opts = GetoptLong.new(
[ "--size", "-s", GetoptLong::REQUIRED_ARGUMENT ],
[ "--verbose", "-v", GetoptLong::NO_ARGUMENT ],
[ "--term", "-t", GetoptLong::NO_ARGUMENT ],
[ "--query", "-q", GetoptLong::NO_ARGUMENT ],
[ "--check", "--valid", "-c", GetoptLong::NO_ARGUMENT ]
)
opts.each do |opt, arg|
puts "Option: #{opt}, arg #{arg.inspect}"
opts.terminate if (opt == '--term')
end
puts "Remaining args: #{ARGV.join(', ')}"
produces:
Option: --size, arg "10k"
Option: --verbose, arg ""
Option: --term, arg ""
Remaining args: -q, a.txt, b.doc
Returns
true if option processing has been terminated.
module mkmf
Index:
create_makefile
dir_config
find_library
have_func
have_header
have_library
The
mkmf library is used by Ruby extension modules to help
create
Makefiles. When writing an extension, you create a
program named ``
extconf.rb'', which may be as simple as:
require 'mkmf'
create_makefile("Test")
When run, this script will produce a
Makefile suited to the
target platform.
mkmf contains several methods you can use
to find libraries and include files and to set compiler flags.
For more information on creating extension modules, see Chapter
17, which begins on page 169.
constants
PLATFORM
varies
A constant string that describes the
platform on which Ruby is running, such as ``mswin32'' or
``i686-linux.''
$CFLAGS
Global variable for compiler flags.
$LDFLAGS
Global variable for linker flags.
instance methods
Creates a
Makefile for an extension named
target.
If this method is not called, no
Makefile is created.
Looks for directory configuration options for
name given
as arguments to this program or to the original build of Ruby.
These arguments may be one of:
--with-
name
-dir=directory
--with-
name
-include=directory
--with-
name
-lib=directory
The given directories will be added to the appropriate search
paths (include or link) in the
Makefile.
find_library
find_library(
name,
function,
[
path
]+
)
->
true or
false
Same as
have_library, but will also search in the given
directory paths.
have_func
have_func(
function )
->
true or
false
If the named
function exists in the standard compile environment,
adds the directive -DHAVE_
FUNCTION
to the compile command in the
Makefile and returns
true.
If the given header file can be found in the
standard search path, adds the directive -DHAVE_
HEADER
to the compile command in the
Makefile and returns
true.
have_library
have_library(
library,
function ) ->
true or
false
If the given function exists in the named library, which must exist in
the standard search path or in a directory added with
dir_config, adds the library to the link command
in the
Makefile and returns
true.
module ParseDate
Index:
parsedate
The
ParseDate module defines a single method,
ParseDate::parsedate, which converts a date and/or time string
into its constituents. It uses heuristics that handle a wide
variety of date and time formats, including a subset of ISO 8601,
Unix
ctime, and most common written variants. The following table shows
some examples.
StringGuess?
yy
mm
dd
hh
min
sec
zone
wd
1999年09月05日 23:55:21+0900
F
1999
9
5
23
55
21
+0900
--
1983年12月25日
F
1983
12
25
--
--
--
--
--
1965年11月10日 T13:45
F
1965
11
10
13
45
--
--
--
10/9/75 1:30pm
F
75
10
9
13
30
--
--
--
10/9/75 1:30pm
T
1975
10
9
13
30
--
--
--
Mon Feb 28 17:15:49 CST 2000
F
2000
2
28
17
15
49
CST
1
Tue, 02-Mar-99 11:20:32 GMT
F
99
3
2
11
20
32
GMT
2
Tue, 02-Mar-99 11:20:32 GMT
T
1999
3
2
11
20
32
GMT
2
12-January-1990, 04:00 WET
F
1990
1
12
4
0
--
WET
--
4/3/99
F
99
4
3
--
--
--
--
--
4/3/99
T
1999
4
3
--
--
--
--
--
10th February, 1976
F
1976
2
10
--
--
--
--
--
March 1st, 84
T
1984
3
1
--
--
--
--
--
Friday
F
--
--
--
--
--
--
--
5
class methods
parsedate
ref.parsedate(
aString,
guessYear=
false )
-> [
year,
mon,
mday,
hour,
min,
sec,
zone,
wday
]
Parses a string containing a date and/or a time, returning an
array of
Fixnum objects containing the various components.
nil is returned for fields that cannot be parsed from
aString. If the result contains a year that is less than
100 and
guessYear is true,
parsedate will return
a year value equal to
year plus 2000 if
year is less
than 69,
year plus 1900 otherwise.
Library: profile
The
profile library prints to
$stderr a summary
of the number of calls to, and the time spent in, each method in a
Ruby program. The output is sorted by the total time spent in each
method. Profiling can be enabled from the command line using the
-r
profile option, or from within a source program by
requiring the
profile module.
require 'profile'
def ackerman(m, n)
if m == 0 then n+1
elsif n == 0 and m > 0 then ackerman(m-1, 1)
else ackerman(m-1, ackerman(m, n-1))
end
end
ackerman(3,3)
produces:
time seconds seconds calls ms/call ms/call name
74.17 2.47 2.47 2432 1.02 41.95 Object#ackerman
17.42 3.05 0.58 3676 0.16 0.16 Fixnum#==
5.71 3.24 0.19 2431 0.08 0.08 Fixnum#-
2.70 3.33 0.09 1188 0.08 0.08 Fixnum#+
0.00 3.33 0.00 1 0.00 0.00 Module#method_added
0.00 3.33 0.00 57 0.00 0.00 Fixnum#>
0.00 3.33 0.00 1 0.00 3330.00 #toplevel
class PStore
Parent:
Object
Version:
1.6
Index:
new
[ ]
[ ]=
abort
commit
path
root?
roots
transaction
The
PStore class provides transactional, file-based
persistent storage of Ruby objects. The following example stores two
hierarchies in a PStore. The first, identified by the key
``
names'', is an array of Strings. The second, identified by
``
tree'', is a simple binary tree.
require "pstore"
class T
def initialize(val, left=nil, right=nil)
@val, @left, @right = val, left, right
end
def to_a
[ @val, @left.to_a, @right.to_a ]
end
end
store = PStore.new("/tmp/store")
store.transaction do
store['names'] = [ 'Douglas', 'Barenberg', 'Meyer' ]
store['tree'] = T.new('top',
T.new('A', T.new('B')),
T.new('C', T.new('D', nil, T.new('E'))))
end
# now read it back in
store.transaction do
puts "Roots: #{store.roots.join(', ')}"
puts store['names'].join(', ')
puts store['tree'].to_a.inspect
end
produces:
Roots: names, tree
Douglas, Barenberg, Meyer
["top", ["A", ["B", [], []], []], ["C", ["D", [], ["E", [], []]], []]]
Each
PStore can store several
object hierarchies. Each hierarchy has a root, identified by a key
(often a string). At the start of a
PStore transaction, these
hierarchies are read from a disk file and made available to the Ruby
program. At the end of the transaction, the hierarchies are written
back to the file. Any changes made to objects in these hierarchies
are therefore saved on disk, to be read at the start of the next
transaction that uses that file.
In normal use, a
PStore object is created and then is used one or
more times to control a transaction. Within the body of the
transaction, any object hierarchies that had previously been saved
are made available, and any changes to object hierarchies, and any
new hierarchies, are written back to the file at the end.
class methods
new
PStore.new(
aFilename )
->
aPStore
Returns a new
PStore object associated with the given
file. If the file exists, its contents must have been previously
written by
PStore.
instance methods
[ ]
ref[
anObject ] ->
anOtherObject
Root Access---Returns the root of an object hierarchy identified
by
anObject. An exception is raised if
anObject does
not identify a root.
[ ]=
ref[
anObject ] =
anOtherObject
->
anOtherObject
Root Creation---Sets
anOtherObject as the base of the object
hierarchy to be identified using
anObject.
Terminates this transaction, losing any changes made to the
object hierarchies.
Terminates the current transaction, saving the object hierarchies
into the store's file.
Returns the name of the file associated with this store.
root?
ref.root?(
anObject )
->
true or
false
Returns
true if
anObject is the key of a root in
this store.
roots
ref.roots ->
anArray
Returns an array containing the keys of the root objects
available in this store.
transaction
ref.transaction {|
ref | block }
->
anObject
If the file associated with
ref exists, reads in the object
hierarchies from it. It then executes the associated block, passing
in
ref. The block may use this parameter to access the roots
of the hierarchies and hence access the persistent objects. If
the block calls
PStore#abort, or if it raises an exception,
no data is saved back to the associated file. Otherwise, if it
invokes
PStore#commit, or if it terminates normally, the
object hierarchies are written back to the file. The value
returned is the value returned by the block.
class Tempfile
Parent:
[IO]
Version:
1.6
Index:
new
close
open
path
require "tempfile"
tf = Tempfile.new("afile")
tf.path
サ
"/tmp/afile32146.0"
tf.puts("Cosi Fan Tutte")
サ
nil
tf.close
サ
nil
tf.open
サ
#<File:0x40196fc8>
tf.gets
サ
"Cosi Fan Tutte\n"
tf.close(true)
サ
#<File:0x40196fc8>
Class
Tempfile creates managed temporary files. Although they
behave the same as any other
IO objects, temporary files are
automatically deleted when the Ruby program terminates. Once a
Tempfile object has been created, the underlying file may be
opened and closed a number of times in succession.
Tempfile does not directly inherit from
IO. Instead, it
delegates calls to a
File object. From the programmer's
perspective, apart from the unusual
new,
open, and
close semantics, a
Tempfile object behaves as if it
were an
IO object.
class methods
new
Tempfile.new(
basename,
tmpdir=<see below> )
->
ref
Constructs a temporary file in the given directory. The file
name is built by concatenating
basename, the current
process id and (as an extension) a unique sequence number. If
the
tmpdir parameter is not supplied, it defaults to the
value of one of the environment variables
TMPDIR,
TMP,
or
TEMP, or to the directory
/tmp.
The file is then opened using mode ``w+'', which allows reading
and writing and deletes any existing content (see Table
22.5 on page 326).
open
Tempfile.open(
basename,
tmpdir )
->
ref
Synonym for
Tempfile.new.
instance methods
close
ref.close(
final=
false )
Closes
ref. If
final is
true, deletes the underlying
real file. If
final is
false,
ref may be
subsequently reopened. In all cases, the underlying file is
deleted when the program terminates.
Reopens
ref using mode ``r+'', which allows reading and
writing but does not delete existing content.
Returns the full path of the underlying file.
class Mutex
Parent:
Object
Version:
1.6
Index:
lock
locked?
synchronize
try_lock
unlock
require 'thread'
sema4 = Mutex.new
a = Thread.new {
sema4.synchronize {
# access shared resource
}
}
b = Thread.new {
sema4.synchronize {
# access shared resource
}
}
Mutex implements a simple semaphore that can be used to
coordinate access to shared data from multiple concurrent threads.
instance methods
Attempts to grab the lock and waits if it isn't available.
locked?
ref.locked?
->
true or
false
Returns
true if this lock is currently held by some
thread.
Obtains a lock (using
Mutex#lock), runs the block,
and releases the lock when the block completes.
Attempts to obtain the lock and returns
immediately. Returns
true if the lock was granted.
unlock
ref.unlock
->
ref or
nil
Releases the lock. Returns
nil if
ref wasn't locked.
class ConditionVariable
Parent:
Object
Version:
1.6
Index:
broadcast
signal
wait
require 'thread'
mutex = Mutex.new
resource = ConditionVariable.new
a = Thread.new {
mutex.synchronize {
# Thread 'a' now needs the resource
resource.wait(mutex)
# 'a' can now have the resource
}
}
b = Thread.new {
mutex.synchronize {
# Thread 'b' has finished using the resource
resource.signal
}
}
ConditionVariable objects augment class
Mutex. Using
condition variables, it is possible to suspend while in the middle
of a critical section until a resource becomes available (see the discussion
on page 117).
instance methods
Wakes up all threads waiting for this lock.
Wakes up the first thread in line waiting for this lock.
wait
ref.wait(
aMutex )
->
aMutex
Releases the lock held in
aMutex and waits; reacquires
the lock on wakeup.
Library: timeout
require "timeout"
for snooze in 1..2
puts "About to sleep for #{snooze}"
timeout(1.5) do
sleep(snooze)
end
puts "That was refreshing"
end
produces:
About to sleep for 1
That was refreshing
About to sleep for 2
/tc/usr/lib/ruby/1.6/timeout.rb:37: execution expired (TimeoutError)
from prog.rb:5:in `timeout'
from prog.rb:5
from prog.rb:3:in `each'
from prog.rb:3
The
timeout method takes a single parameter, representing
a timeout period in seconds, and a block. The block is executed, and
a timer is run concurrently. If the block terminates before the
timeout,
timeout returns
true. Otherwise, a
TimeoutError exception is raised.
class WeakRef
Parent:
Delegator
Version:
1.6
Index:
new
weakref_alive?
require "weakref"
ref = "fol de rol"
puts "Initial object is #{ref}"
ref = WeakRef.new(ref)
puts "Weak reference is #{ref}"
ObjectSpace.garbage_collect
puts "But then it is #{ref}"
produces:
Initial object is fol de rol
Weak reference is fol de rol
prog.rb:8: Illegal Reference - probably recycled (WeakRef::RefError)
In Ruby, objects are not eligible for garbage collection if there
are still references to them. Normally, this is a Good Thing---it
would be disconcerting to have an object simply evaporate while you
were using it. However, sometimes you may need more flexibility. For
example, you might want to implement an in-memory cache of commonly
used file contents. As you read more files, the cache grows. At some
point, you may run low on memory. The garbage collector will be
invoked, but the objects in the cache are all referenced by the
cache data structures, and so will not be deleted.
A weak reference behaves
exactly as any normal object reference with one important
exception---the referenced object may be garbage collected, even
while references to it exist. In the cache example, if the cached
files were accessed using weak references, once memory runs low they
will be garbage collected, freeing memory for the rest of the
application.
Weak references introduce a slight complexity. As the object
referenced can be deleted by garbage collection at any time, code
that accesses these objects must take care to ensure that the
references are valid. Two techniques can be used. First, the code
can reference the objects normally. Any attempt to reference an
object that has been garbage collected will raise a
WeakRef::RefError exception.
An alternative approach is to use the
WeakRef#weakref_alive?
method to check that a reference is valid before using it. Garbage
collection must be disabled during the test and subsequent reference
to the object. In a single-threaded program, you could use something
like:
ref = WeakRef.new(someObject)
#
# .. some time later
#
gcWasDisabled = GC.disable
if ref.weakref_alive?
# do stuff with 'ref'
end
GC.enable unless gcWasDisabled
class methods
new
WeakRef.new(
anObject )
->
ref
Creates and returns a weak reference to
anObject. All
future references to
anObject should be made using
ref.
instance methods
Returns
false if the object referenced by
ref has
been garbage collected.
Extracted from the book "Programming Ruby -
The Pragmatic Programmer's Guide"
Copyright
©
2001 by Addison Wesley Longman, Inc. This material may
be distributed only subject to the terms and conditions set forth in
the Open Publication License, v1.0 or later (the latest version is
presently available at
http://www.opencontent.org/openpub/)).
Distribution of substantively modified versions of this document is
prohibited without the explicit permission of the copyright holder.
Distribution of the work or derivative of the work in any standard
(paper) book form is prohibited unless prior permission is obtained
from the copyright holder.