Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/polettix/ordeal-model

Manage cards and decks
https://github.com/polettix/ordeal-model

Last synced: 27 days ago
JSON representation

Manage cards and decks

Awesome Lists containing this project

README

        

# NAME

Ordeal::Model - Manage cards and decks

# VERSION

This document describes Ordeal::Model version {{\[ version \]}}.



Build Status


Perl Version


Current CPAN version


Kwalitee


CPAN Testers


CPAN Testers Matrix

# SYNOPSIS

use Ordeal::Model;

# leverage Ordeal::Model::Backend::PlainFile
my $model = Ordeal::Model->new(PlainFile => [base_directory => $dir]);

# get a card by identifier
my $card = $model->get_card($card_id);

# get a deck by identifier
my $deck = $model->get_deck($deck_id);

# evaluate a complex expression, getting a "shuffle" back
my $shuffle = $model->evaluate($expression, %args);

# you can pre-compute the parsing of an expression, e.g. for caching
my $ast = $model->parse($expression);
$shuffle = $model->evaluate($ast, %args);

# override to provide an alternative resolution algorithm
my $backend_class = $model->resolve_backend_name($some_name);

# DESCRIPTION

This document is about `Ordeal::Model`, a module allows you to manage
cards and group them into decks. The main goal is to provide an easy
mean to shuffle decks and get some cards out of them.

In the document you will find a reference for the main module. If you
are interested into _using_ it, head to [Ordeal::Model::Tutorial](https://metacpan.org/pod/Ordeal::Model::Tutorial)
which provides a gentler introduction.

# METHODS

## **evaluate**

my $shuffle = $model>evaluate($expression_or_ast, %args);

Evaluate an input expression, or the AST resulting from its parsing.
Calls ["parse"](#parse) if the input is not already in AST form. See
[Ordeal::Model::Parser](https://metacpan.org/pod/Ordeal::Model::Parser) for the gory details about the grammar accepted
for expressions, and to the code for [Ordeal::Model::Evaluator](https://metacpan.org/pod/Ordeal::Model::Evaluator) to
figure out how to structure an AST (which you should not need to!). For
a gentler introduction (who loves to read a grammar, after all?!?) see
[Ordeal::Model::Tutorial](https://metacpan.org/pod/Ordeal::Model::Tutorial).

The optional additional arguments in `%args` are used for random source
selection if there is any suitable key among the following:

- `random_source`

a random source conforming to the interface provided by
[Ordeal::Model::ChaCha20](https://metacpan.org/pod/Ordeal::Model::ChaCha20);

- `random_source_state`

opaque data useful for fully restoring the state of a random data in an
instance of [Ordeal::Model::ChaCha20](https://metacpan.org/pod/Ordeal::Model::ChaCha20);

- `seed`

seed value used for creating a new instance of [Ordeal::Model::ChaCha20](https://metacpan.org/pod/Ordeal::Model::ChaCha20).

The key above are in order of precedence, i.e. `random_source` is tried first,
then `random_source_state`, then `seed` at last.

This method returns an [Ordeal::Model::Shuffle](https://metacpan.org/pod/Ordeal::Model::Shuffle) object that you can use
to draw cards from, e.g.:

my @two_cards = $shuffle->draw(2);
my @three_more_cards = $shuffle->draw(3);

Be careful that [Ordeal::Model::Shuffle](https://metacpan.org/pod/Ordeal::Model::Shuffle) will throw an exception if you
try to draw more cards than available!

## **get\_card**

my $card = $model->get_card($id);

get an [Ordeal::Model::Card](https://metacpan.org/pod/Ordeal::Model::Card) by identifier.

## **get\_deck**

my $deck = $model->get_deck($id);

get an [Ordeal::Model::Deck](https://metacpan.org/pod/Ordeal::Model::Deck) by identifier.

## **get\_deck\_ids**

my @ids = $model_>get_deck_ids;

get a list of available deck identifiers. Each can be used with
["get\_deck"](#get_deck) to load a deck.

## **new**

my $model = Ordeal::Model->new(%args); # OR
my $model = Ordeal::Model->new(\%args);

constructor.

The `%args` hash can contain only one key/value pair. If the key is
`backend`, then the value MUST be either a blessed object to be used as
backend, or an array reference with information suitable for generating
one. In particular, the array form should contain a name that can be
resolved through ["resolve\_backend\_name"](#resolve_backend_name) as the first item, and any
argument for the resolved class as the remaining items, in order as they
are supposed to be consumed by its `new` method.

Otherwise, the key is considered a name suitable for
["resolve\_backend\_name"](#resolve_backend_name), and the associated value MUST be an array/hash
reference that is expanded and passed to the `new` method associated to
the class resolved from the name.

Too complicated? A few examples will hopefull help:

use Ordeal::Model::Backend::PlainFile;
my $pf = Ordeal::Model::Backend::PlainFile->new;

# Case: backend => $blessed_reference
my $m1 = Ordeal::Model->new(backend => $pf);

# Case: backend => $array_ref
my $m2 = Ordeal::Model->new(
backend => [PlainFile => base_directory => '/some/path']);

# Case: key different from 'backend', points to an array reference
my $m3 = Ordeal::Model->new(PlainFile => [base_directory => '/some/path']);

# Case: key different from 'backend', points to a hash reference
my $m4 = Ordeal::Model->new(PlainFile => {base_directory => '/some/path'});

If `%args` contains nothing, then [Ordeal::Model::Backend::PlainFile](https://metacpan.org/pod/Ordeal::Model::Backend::PlainFile)
is used with default parameters for its constructor.

## **parse**

my $ast = $model>parse($expression);

Parse an expression and return an AST suitable for ["evaluate"](#evaluate).

## **random\_source**

# in constructor
Ordeal::Model->new(random_source => $rs, ...);

my $rs = $shuffler>random_source;
$shuffler>random_source($rs);

Accessor for the source of randomness. It defaults to an instance of
[Ordeal::Model::ChaCha20](https://metacpan.org/pod/Ordeal::Model::ChaCha20), set at construction time. It _MAY_ be used
by ["evaluate"](#evaluate) unless it is overridden by arguments.

## **resolve\_backend\_name**

my $class_name = $model->resolve_backend_name($name);
my $class_name = $package>resolve_backend_name($name);

resolve a `$name` for a backend to use - this is a class method.

The resolution process is as follows:

- if `$name` begins with a `-`, then it is considered directly the class
name to be used after removing the initial `-` character. Examples:

$name = '-Whatever'; # resolves to class Whatever
$name = '-Whatever::Module'; # resolves to class Whatever::Module

- otherwise, if it contains `::`, but does not begin with `::`, then it is
again considered as the full name to use for the class. Example:

$name = 'Whatever::Module'; # resolves to class Whatever::Module

- otherwise, it is used to search for a candidate class, first in namespace
`$package . '::Backend::'`, then in namespace
`Ordeal::Model::Backend::`. Examples (assuming that the package you call
it with is `Ordeal::Model`):

$name = 'Whatever'; # resolves to Ordeal::Model::Backend::Whatever
$name = '::W::Ever': # resolves to Ordeal::Model::Backend::W::Ever

If you want to be on the _safe side_, always pre-pend `::` if you want
to activate the automatic search for a backend class, and always pre-pend
`-` if you want to specify the full backend class name.

This method is used by ["new"](#new) behind the scenes, so you can override it
to provide a different resolution algorithm.

# BUGS AND LIMITATIONS

The code leverages some experimental Perl features like signatures and
postderef; for this reason, at least perl 5.20 will be needed.

Report bugs through GitHub (patches welcome) at
[https://github.com/polettix/Ordeal-Model](https://github.com/polettix/Ordeal-Model).

# AUTHOR

Flavio Poletti

# COPYRIGHT AND LICENSE

Copyright (C) 2018-2020 by Flavio Poletti

This module is free software. You can redistribute it and/or modify it
under the terms of the Artistic License 2.0.

This program is distributed in the hope that it will be useful, but
without any warranty; without even the implied warranty of
merchantability or fitness for a particular purpose.