Fortune
NAME
Fortune - Unix fortune database interface
SYNOPSIS
use Fortune;
## Object-oriented interface
my $fortune = Fortune.new: '/path/to/database';
my $pick = $fortune.fortune.pick;
$fortune.fortune.append: (q:to/HERE/).chomp;
Arnold's Laws of Documentation:
(1) If it should exist, it doesn't.
(2) If it does exist, it's out of date.
(3) Only documentation for useless programs transcends the
first two laws.
HERE
$fortune.write: '/path/to/new/database', :header('/path/to/header');
## Some convenience subs
strfile '/path/to/database', '/path/to/header';
$pick = fortune;
DESCRIPTION
Fortune is a Raku module that provides an interface for reading and writing Unix fortune files, both the text database files and the binary header files.
class Fortune
Attributes
fortune
has Str @.fortune is rw
Str array of fortunes. Manipulating this array is how you can modify a
fortune database.
# Add a fortune
$fortune.fortune.append: "A new fortune";
# Remove a fortune
$fortune.fortune.pop;
# Sort fortunes
$fortune.fortune.=sort;
# Shuffle fortunes
$fortune.fortune.=pick(*);
# etc. etc.
order
has FortuneOrder $.order is rw
Attribute that determines the order to write the header's offset table in. Does
not determine the order of the fortunes stored in the object's fortune
attribute.
See the FortuneOrder documentation below for documentation on valid values
for order.
rot13
has Bool $.rot13 is rw
Bool that determines whether the source fortune database was ROT-13
ciphered or not. When set to True, the Fortune object will read and write
databases as if they were ROT-13 ciphered.
delimit
has Char $.delimit is rw
Character that is used for delimitting lines in a source fortune database.
Is usually a single percentage sign ('%'). delimit must be a string that
represents a single ASCII character.
version
has Int $.version is rw
Version number of the fortune header. Valid values are 1 and 2. Version 1
is the version used by most strfile implementations, version 2 is the version
used by OpenBSD. The difference between the two versions is the way they store
offsets in the fortune header: 1 stores offsets as 64-bit unsigned integars
while 2 stores them as 32-bit unsigned integars. The version has no effect
on the source fortune database.
Methods
new
method new(
$database?,
:$header,
:@fortune,
FortuneOrder :$order,
Bool :$rot13,
Char :$delimit,
Int :$version
)
Returns a new Fortune object. Will either create an entirely new database
if $database is not provided, or read from an existing one if $database
is provided.
$database is the path to the database to read fortunes from. The fortunes can
be accessed and manipulated from the object's fortune attribute.
$header is the path to the database's corresponding binary header to read
from. If $header is a value that evaluates to False, new will not
attempt to read any header file. By default, $header will either be
$database with the '.dat' suffix appended if $database was provided
and such a header does exist, otherwise it will be set to False. Please note
that when reading from $header, new will override any custom attributes
that were supplied.
@fortune is the list of fortune strings to supply for the fortune
attribute. Defaults to Empty. If $database is also provided, new will
append the list of fortunes read from $database to the list provided by
@fortune.
$order is the value to supply for the order attribute. Defaults to
FORTUNE_UNORDER.
$rot13 is the value to supply for the rot13 attribute. Defaults to
False.
$delimit is the value to supply for the delimit attribute. Defaults to
'%'.
$version is the value to supply for the version attribute. Defaults to
1.
read
method read(
$database,
:$header,
Bool :$append
)
Reads data from the source database $database and (optionally) from the
header $header.
$header will, by default, be $database with the '.dat' suffix if such
a file exists, or False otherwise. If you
do not wish to read from an existing header, $header can be set to False.
$append is a Bool determining whether to append new fortunes to the
fortunes array or to overwrite it. Defautls to False.
Returns True, if successful.
read_header
method read_header($header)
Reads data from the header file $header.
Returns True, if successful.
read_database
method read_database(
$database,
Char :$delimit,
Bool :$rot13,
Bool :$append
)
Reads fortunes from the database file $database.
$delimit is the delimitting character to use when reading $database. Does
not modify the delimit attribute. Defaults to the value of the delimit
attribute.
$rot13 determines whether to ROT-13 cipher the fortunes in $database. Does
not modify the rot13 attribute. Defaults to the value of the rot13
attribute.
$append is a Bool determining whether to override the current fortune list
in fortune, or to just append to it. Defaults to False.
Returns True, if successful.
write
method write(
$database,
:$header
)
Write fortune database to $database and (optionally) fortune header to
$header.
By default, $header will be $database with the '.dat' suffix. If set
to any value that evaluates to False, write will not try to write a
header file.
Returns list of IO objects for each written file.
write_database
method write_database($database)
Write fortune database to $database.
Returns IO object of written database.
write_header
method write_header($header)
Write fortune header to $header.
Returns IO object of written header.
Subroutines
The following subroutines were written to provide simple convenience functions for those who do not wish to interact with the object-oriented part of this module.
strfile
sub strfile(
$database,
$header?,
Char :$delimit,
FortuneOrder :$order,
Bool :$rot13,
Int :$version
)
Subroutine emulating the strfile(8) utility. Reads fortunes from $database
and generates a corresponding fortune header to $header. If not supplied,
$header will default to $database with the '.dat' suffix.
$delimit is the delimitting character $database uses. Defaults to
'%'.
$order is the order to write the offset table in. Defaults to
FORTUNE_UNORDER.
$rot13 is a Bool determining whether the source database was ROT-13
ciphered or not. Defaults to False.
$version is the version number to use for the generated header. Defaults to
1.
Returns the IO object of the written header.
fortune
multi sub fortune(
Bool :$short,
Bool :$long
)
multi sub fortune(
$database,
:$header,
Bool :$short,
Bool :$long,
Bool :$equal,
Bool :$all,
Bool :$offensive,
Char :$delimit,
Bool :$rot13
)
multi sub fortune(
$dir,
Bool :$short,
Bool :$long,
Bool :$equal,
Bool :$all,
Bool :$offensive,
Char :$delimit,
Bool :$rot13
)
Subroutine somewhat emulating the fortune(6) utility. Picks a random fortune
from a supplied database and returns it.
When ran without providing a fortune file/directory, returns a fortune from this module's own database.
When given a file as an argument, returns a random fortune from that file.
When given a directory as argument, returns a random fortune from one of the databases in that directory.
$header is the path to the header file to read from. Defaults to $database
with the '.dat' suffix, or False if such a file does not exist. When
False, fortune will not try to read any header file.
$short is a Bool determining whether to only pick from short fortunes.
A short fortune is a fortune of 160 characters or less. Defaults to False.
$long is a Bool determining whether to only pick from long fortunes. A
long fortune is a fortune that has more than 160 characters. Defaults to
False.
$equal is a Bool determining whether to treat each fortune file in
$dir of equal size. Is False by default, which means that fortune() is
more likely to pick a fortune from a larger file.
$all is a Bool determining whether to include all fortunes files,
including offensive ones, when picking a fortune. Is meaningless unless the
fortune argument is a directory.
$offensive is a Bool that means fortune() will only pick offensive
fortunes, which are fortunes located in a file with a '-o' suffix. Is
meaningless unless the fortune argument is a directory. Also, to quote the
fortune(6) manpage:
Please, please, please request a potentially offensive fortune if and only if
you believe, deep down in your heart, that you are willing to be offended.
(And that if you are, you'll just quit using [:offensive] rather than give us
grief about it, okay?)
... let us keep in mind the basic governing philosophy of The Brotherhood,
as handsomely summarized in these words: we believe in healthy, hearty
laughter -- at the expense of the whole human race, if needs be. Needs be.
--H. Allen Smith, "Rude Jokes"
$delimit is the delimitting character to use when reading from a database.
Defaults to '%'.
$rot13 is a Bool determining whether the database is ROT-13 ciphered or
not. Defaults to False.
This subroutine caches the Fortune object it creates from reading a database,
and will re-use it as long as it has the same arguments as the previous
fortune call. This makes it efficient to call this subroutine on the same
database multiple times.
Global Variables
DATABASE
our constant $DATABASE
IO object of Fortune's personal fortune database, which is the one used by
default by fortune() and the rfortune script. Can be accessed via
$Fortune::DATABASE.
enum FortuneOrder
enum FortuneOrder <
FORTUNE_UNORDER
FORTUNE_ORDER
FORTUNE_FC_ORDER
FORTUNE_RANDOM
>
Enumeration representing the various ways a header file can order their offset tables.
FORTUNE_UNORDERThe offsets are ordered in the same way the fortunes are ordered in the
fortunearray.FORTUNE_ORDERThe offsets are ordered alphabetically.
FORTUNE_FC_ORDERThe offsets are ordered alphabetically, case-insensitive.
FORTUNE_RANDOMThe offsets are ordered randomly.
AUTHOR
Written by Samuel Young, [email protected].
The source for this module can be found on its Codeberg page. Comments and pull requests are welcome.
COPYRIGHT
Copyright 2025, Samuel Young
This program is free software; you can redistribute it and/or modify it under the terms of the Artistic License 2.0.
SEE ALSO
fortune(6), strfile(8)