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 thelib
subdirectory of the standard Ruby distribution.
class Complex
Parent:
Numeric
Version:
1.6
Index:
newArithmetic operations<=>==absabs2argconjugateimagepolarrealto_fto_ito_rto_srequire "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
constantsComplex::I
0 +1i
class methods
new
Complex.new(a,b ) ->aComplex
Returns a + bi.
In addition to theComplex.new
constructor, theComplex
library defines the methodNumeric.im
, such thataNumeric.im
returns 0 +aNumerici. Complex numbers are also constructed using the global methodComplex
, 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
ComplexComplex(a.real -b.image,a.image +b.real )
Number
ComplexComplex(a -b.image,b.real )
instance methods
Arithmetic operations
Performs various arithmetic operations onref.
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
Returnsref.abs<=>
other.abs.
==
ref ==anObject ->true
orfalse
IfanObject is a complex number, returnstrue
if its real and imaginary parts matchref. IfanObject is a simple number, returnstrue
ifref.real
equalsanObject andref.image
is zero. Otherwise, attempts to coerceanObject to a complex number and compares the result.
abs
ref.abs ->aFloat
Absolute value.
abs2
ref.abs2 ->aFloat
Square of absolute value.
arg
ref.arg ->aFloat
Argument (angle from (1,0)).
conjugate
ref.conjugate ->aComplex
Complex conjugate.
image
ref.image ->aNumeric
The imaginary part ofref.
polar
ref.polar ->anArray
Returns the two-element array: [c.abs,c.arg].
real
ref.real ->aNumeric
The real part ofref.
to_f
ref.to_f ->aComplex
ReturnsComplex(real.to_f, image.to_f)
.
to_i
ref.to_i ->aComplex
ReturnsComplex(real.to_i, image.to_i)
.
to_r
ref.to_r ->aComplex
ReturnsComplex(real.to_r, image.to_r)
, converting both parts of the complex to a rational number.
to_s
ref.to_s ->aString
String representation ofref.
In addition, theMath
functionssqrt
,exp
,cos
,sin
,tan
,log
,log10
, andatan2
are extended to support aComplex
argument.
class Date
Parent:
Object
Version:
1.6
Index:
exist2? exist? existw? gregorian_leap? julian_leap? leap? new new1 new2 new3 neww todayAccessors+--<<<=>===>>downtoenglandgregorianitalyjdjulianleap?mjdnewsgnextns?os?sgstepsuccto_suptorequire '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]
Thedate
library implements classDate
, 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. TheDate
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. TheDate
class allows you to determine whether to implement the cutover in 1582 (theDate::ITALY
option), 1752 (Date::ENGLAND
), or another date of your choosing.
TheDate
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 fromyear, 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, orJULIAN
, 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).
ClassDate
exports the constant arraysDate::MONTHNAMES
andDate::DAYNAMES
, which can be indexed bymon andwday values to return the corresponding English names.
TheDate
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 namedexist..?
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 ayear andyday into a Julian day number, returningnil
on error.
exist?
Date.exist?(year,mon,mday,sg=Date::ITALY
) ->jd
Converts ayear,mon, andmday into a Julian day number, ornil
if the parameters are invalid.
existw?
Date.existw?(cyear,cweek,cwday,sg=Date::ITALY
) ->jd
Converts acyear,cweek, andcwday into a Julian day number.
gregorian_leap?
Date.gregorian_leap?(year ) ->true
orfalse
Ifyear does not end with ``00'', returnstrue
ifyear is divisible by 4, otherwise returnstrue
ifyear is divisible by 400.
julian_leap?
Date.julian_leap?(year ) ->true
orfalse
Returnstrue
ifyear is divisible by 4.
leap?
Date.leap?(year ) ->true
orfalse
Synonym forDate.gregorian_leap?
.
new
Date.new(year=-4712,mon=1,mday=1,sg=Date::ITALY
) ->aNewDate
Returns aDate
for the givenyear,mon, andmday. Ifmon is negative, it counts back from the end of the year. Ifmday is negative, it counts back from the end of the month.
new1
Date.new1(jd,sg=Date::ITALY
) ->aNewDate
Creates aDate
corresponding to the given Julian day number.
new2
Date.new2(year=-4712,yday=1,sg=Date::ITALY
) ->aNewDate
Returns aDate
for the givenyear andyday. Ifyday 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 forDate.new
.
neww
Date.neww(cyear=1582,cweek=41,cwday=5,sg=Date::ITALY
) ->aNewDate
Returns aDate
for the givencyear,cweek, andcwday. Ifcweek is negative, it counts back from the end of the year. Ifcwday is negative, it counts back from the end of the week.
today
Date.today(sg=Date::ITALY
) ->aNewDate
Returns aDate
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 ofref as a number.
+
ref +anInteger ->aNewDate
Returns a newDate
anInteger days fromref.
--
ref-
anInteger ->aNewDate
ref-
anOtherDate ->anInteger
The first form returns a newDate
anInteger days beforeref. The second form returns the number of days betweenref andanOtherDate.
<<
ref <<anInteger ->aNewDate
Returns a newDate
formed by subtractinganInteger months toref, adjusting themday value back to the last day of the month if it otherwise exceeds it.
<=>
ref <=>anOther -> -1, 0, +1
anOther must be aNumeric
, in which case it is treated as a Julian day number, or aDate
. Returns -1, 0, +1 ifref is less than, equal to, or greater thananOther. See moduleComparable
on page 402.
===
ref ===anOther ->true
orfalse
anOther must be aNumeric
, in which case it is treated as a Julian day number, or aDate
. Returnstrue
if the Julian day number ofanOther is the same asref.
>>
ref >>anInteger ->aNewDate
Returns a newDate
formed by addinganInteger months toref, adjusting themday 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 fromref down toaDateMin.
england
ref.england ->aDate
Equivalent toref.newsg(Date::ENGLAND)
.
gregorian
ref.gregorian ->aDate
Equivalent toref.newsg(Date::GREGORIAN)
.
italy
ref.italy ->aDate
Equivalent toref.newsg(Date::ITALY)
.
jd
ref.jd ->jd
Returns the Julian day number forref.
julian
ref.julian ->aDate
Equivalent toref.newsg(Date::JULIAN)
.
leap?
ref.leap? ->true
orfalse
Returnstrue
ifref falls within a leap year.
mjd
ref.mjd ->mjd
Returns the Julian day number ofref converted to a modified Julian day number.
newsg
ref.newsg(sg=Date::ITALY
) ->aNewDate
Returns a newDate
.
next
ref.next ->aNewDate
Synonym forref.succ.
ns?
ref.ns? ->true
orfalse
Returnstrue
ifref falls in the period of New Style dates.
os?
ref.os? ->true
orfalse
Returnstrue
ifref falls in the period of Old Style dates.
sg
ref.sg ->anInteger
Returns the Julian day number of the start of New Style dates forref.
step
ref.step(aDateLimit,step ) {| date | block }
->ref
Invokes block with dates starting atref, incrementing bystep days, ending at the first date greater thanaDateLimit (less than for a negative step).
succ
ref.succ ->aNewDate
Returns the date ofref plus one day.
to_s
ref.to_s ->aString
Returnsself
as ``year-mon-mday.''
upto
ref.upto(aDateMax ) {| date | block }
->ref
Invokes block with dates fromref toaDateMax.
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 prunerequire "find"produces:
Find.find("/etc/passwd", "/var/spool/lp1", ".") do |f|
Find.prune if f == "."
puts f
end
/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.
prune
ref.prune
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 withFind::find
.
class File
Parent:
IO
Version:
1.6
Index:
cmp compare copy cp install makedirs mkpath move mv rm_f safe_unlink syscopyrequire 'ftools'
File.copy 'testfile', 'testfile1'
»true
File.compare 'testfile', 'testfile1'
»true
TheFTools
library adds several methods to the built-inFile
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
orfalse
Synonym forFile.compare
.
compare
ref.compare(name1,name2,verbose=false
) ->true
orfalse
Returnstrue
only if the contents of filesname1 andname2 are identical.
copy
ref.copy(fromName,toName,verbose=false
) ->true
orfalse
Equivalent to callingFile.syscopy
, but logs the attempt to$stderr
ifverbose is notfalse
.
cp
ref.cp(fromName,toName,verbose=false
) ->true
orfalse
Synonym forFile.copy
.
install
ref.install(fromName,toName,aMode=nil
,verbose=false
)
Copies filefromName to filetoName usingFile.syscopy
, unlesstoName already exists and has the same content asfromName. Sets the mode of the resulting file toaMode unlessaMode isnil
.
makedirs
ref.makedirs([dirName]*[,aBoolean] )
Creates the given directories, logging each attempt to$stderr
if the last parameter istrue
. Creates any missing parent directories as required.
mkpath
ref.mkpath([dirName]*[,aBoolean] )
Synonym forFile.makedirs
.
move
ref.move(fromName,toName,verbose=false
) ->true
orfalse
Effectively renamesfromName totoName, logging to$stderr
ifverbose is notfalse
.
mv
ref.mv(fromName,toName,verbose=false
) ->true
orfalse
Synonym forFile.move
.
rm_f
ref.rm_f([fileName]*[,aBoolean] ) ->anInteger
Synonym forFile.safe_unlink
(the name refers to the Unixrm -f
command).
safe_unlink
ref.safe_unlink([fileName]*[,aBoolean] ) ->anInteger ornil
Unlinks (deletes) the given files, logging to$stderr
if the last parameter istrue
. 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, ornil
on error.
syscopy
ref.syscopy(fromName,toName ) ->true
orfalse
Efficiently copies the file namedfromName totoName. IftoName names a directory, the destination will be a file in that directory with the same basename asfromName. After the copy, the file mode oftoName will be the same as that offromName. Returnstrue
on success.
class GetoptLong
Parent:
Object
Version:
1.6
Index:
neweacherror?error_messagegetget_optionorderingordering=quietquiet=quiet?set_optionsterminateterminated?# 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
, orOPTIONAL_ARGUMENT
) specifies howGetoptLong
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 ofGetoptLong
is to reorganize the command line to put the options at the front. This behavior may be changed by settingGetoptLong#ordering=
to one of the constantsPERMUTE
,REQUIRE_ORDER
, orRETURN_IN_ORDER
.POSIXLY_CORRECT
may not be overridden.constants
Per-option constants
NO_ARGUMENT
Flags an option that takes no argument.
OPTIONAL_ARGUMENT
A nonoption following this option will be used as this option's argument.
REQUIRED_ARGUMENT
This option must be followed by an 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. Anyoptions are passed toref.set_options
.
instance methods
each
ref.each {| anOption, anArgument | block }
Loops callingGetoptLong#get
, passing the returned option and argument to the associated block. The loop ends whenget
returnsnil
foranOption.
error?
ref.error? ->anException
Returns anException
object documenting any error that has occurred, ornil
if there has not been an error.
error_message
ref.error_message ->aString
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 foranArgument. If there are no remaining unprocessed options, or if there is an error in option processing andquiet
has been set,nil
is returned foranOption. Otherwise, if there is an error, a message is written to$stderr
and an exception (a subclass ofStandardError
) is raised.
The option string returned is the first option that was given in the corresponding array passed toset_options
.
get_option
ref.get_option -> [anOption,anArgument ]
Synonym forGetoptLong#get
.
ordering
ref.ordering ->aFixnum
Returns the current ordering.
ordering=
ref.ordering =aFixnum
Sets the ordering to one ofPERMUTE
,REQUIRE_ORDER
, orRETURN_IN_ORDER
. Quietly ignored if the environment variablePOSIXLY_CORRECT
is set. Ordering may not be changed once option processing has been started.
quiet
ref.quiet ->true
orfalse
Returns the current value of thequiet
attribute.
quiet=
ref.quiet =true
orfalse
Sets the current value of thequiet
attribute. Iffalse
, any errors encountered are reported to$stderr
.
quiet?
ref.quiet? ->true
orfalse
Synonym forGetoptLong#quiet
.
set_options
ref.set_options([anOptArray]*) ->ref
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 flagsNO_ARGUMENT
,OPTIONAL_ARGUMENT
, orREQUIRED_ARGUMENT
. See the sample code on page 448 for examples of use.
terminate
ref.terminate ->ref
Terminates option processing. Any remaining arguments are written back toARGV
. This may be called from within aGetoptLong#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 inARGV
.
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
terminated?
ref.terminated? ->true
orfalse
Returnstrue
if option processing has been terminated.
module mkmf
Index:
create_makefiledir_configfind_libraryhave_funchave_headerhave_libraryThemkmf
library is used by Ruby extension modules to help createMakefiles
. 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.
constantsPLATFORM
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
create_makefile
create_makefile(target )
Creates aMakefile
for an extension namedtarget. If this method is not called, noMakefile
is created.
dir_config
dir_config(name )
Looks for directory configuration options forname 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 theMakefile
.
find_library
find_library(name,function,[path]+) ->true
orfalse
Same ashave_library
, but will also search in the given directory paths.
have_func
have_func(function ) ->true
orfalse
If the named function exists in the standard compile environment, adds the directive -DHAVE_FUNCTION to the compile command in theMakefile
and returnstrue
.
have_header
have_header(header ) ->true
orfalse
If the given header file can be found in the standard search path, adds the directive -DHAVE_HEADER to the compile command in theMakefile
and returnstrue
.
have_library
have_library(library,function ) ->true
orfalse
If the given function exists in the named library, which must exist in the standard search path or in a directory added withdir_config
, adds the library to the link command in theMakefile
and returnstrue
.
module ParseDate
Index:
parsedateTheParseDate
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, Unixctime
, 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 ofFixnum
objects containing the various components.nil
is returned for fields that cannot be parsed fromaString. If the result contains a year that is less than 100 andguessYear is true,parsedate
will return a year value equal toyear plus 2000 ifyear is less than 69,year plus 1900 otherwise.
Library: profile
Theprofile
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 theprofile
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[ ][ ]=abortcommitpathroot?rootstransactionThePStore
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 aPStore
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 newPStore
object associated with the given file. If the file exists, its contents must have been previously written byPStore
.
instance methods
[ ]
ref[anObject ] ->anOtherObject
Root Access---Returns the root of an object hierarchy identified byanObject. An exception is raised ifanObject does not identify a root.
[ ]=
ref[anObject ] =anOtherObject ->anOtherObject
Root Creation---SetsanOtherObject as the base of the object hierarchy to be identified usinganObject.
abort
ref.abort
Terminates this transaction, losing any changes made to the object hierarchies.
commit
ref.commit
Terminates the current transaction, saving the object hierarchies into the store's file.
path
ref.path ->aString
Returns the name of the file associated with this store.
root?
ref.root?(anObject ) ->true
orfalse
Returnstrue
ifanObject 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 withref exists, reads in the object hierarchies from it. It then executes the associated block, passing inref. The block may use this parameter to access the roots of the hierarchies and hence access the persistent objects. If the block callsPStore#abort
, or if it raises an exception, no data is saved back to the associated file. Otherwise, if it invokesPStore#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:
newcloseopenpathrequire "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>
ClassTempfile
creates managed temporary files. Although they behave the same as any otherIO
objects, temporary files are automatically deleted when the Ruby program terminates. Once aTempfile
object has been created, the underlying file may be opened and closed a number of times in succession.Tempfile
does not directly inherit fromIO
. Instead, it delegates calls to aFile
object. From the programmer's perspective, apart from the unusualnew
,open,
andclose
semantics, aTempfile
object behaves as if it were anIO
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 concatenatingbasename, the current process id and (as an extension) a unique sequence number. If thetmpdir parameter is not supplied, it defaults to the value of one of the environment variablesTMPDIR
,TMP
, orTEMP
, 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).
openTempfile.open(basename,tmpdir ) ->ref
Synonym forTempfile.new
.
instance methods
close
ref.close(final=false
)
Closesref. Iffinal istrue
, deletes the underlying real file. Iffinal isfalse
,ref may be subsequently reopened. In all cases, the underlying file is deleted when the program terminates.
open
ref.open
Reopensref using mode ``r+'', which allows reading and writing but does not delete existing content.
path
ref.path ->aString
Returns the full path of the underlying file.
class Mutex
Parent:
Object
Version:
1.6
Index:
locklocked?synchronizetry_lockunlockrequire '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
lock
ref.lock ->ref
Attempts to grab the lock and waits if it isn't available.
locked?
ref.locked? ->true
orfalse
Returnstrue
if this lock is currently held by some thread.
synchronize
ref.synchronize { block } ->ref
Obtains a lock (usingMutex#lock
), runs the block, and releases the lock when the block completes.
try_lock
ref.try_lock ->true
orfalse
Attempts to obtain the lock and returns immediately. Returnstrue
if the lock was granted.
unlock
ref.unlock ->ref ornil
Releases the lock. Returnsnil
ifref wasn't locked.
class ConditionVariable
Parent:
Object
Version:
1.6
Index:
broadcastsignalwaitrequire '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 classMutex
. 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
broadcast
ref.broadcast
Wakes up all threads waiting for this lock.
signal
ref.signal
Wakes up the first thread in line waiting for this lock.
wait
ref.wait(aMutex ) ->aMutex
Releases the lock held inaMutex 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
returnstrue
. Otherwise, aTimeoutError
exception is raised.class WeakRef
Parent:
Delegator
Version:
1.6
Index:
newweakref_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 toanObject. All future references toanObject should be made usingref.
instance methods
weakref_alive?
ref.weakref_alive? ->true
orfalse
Returnsfalse
if the object referenced byref has been garbage collected.