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.
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.
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_UNORDER
The offsets are ordered in the same way the fortunes are ordered in the fortune
array.
FORTUNE_ORDER
The offsets are ordered alphabetically.
FORTUNE_FC_ORDER
The offsets are ordered alphabetically, case-insensitive.
FORTUNE_RANDOM
The offsets are ordered randomly.
AUTHOR
Written by Samuel Young, samyoung12788@gmail.com.
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)