PrePAN

Sign in to PrePAN

PrePAN provides a place
to discuss your modules.

CLOSE

Requests for Reviews Feed

Devel::JSON Easy JSON output for one-liners

This module is designed for usage with one-liners. The last value of your one-liner (-e) code will be serialized as JSON data. The expression is evaluated in scalar context.

The output will be either UTF-x (UTF-8, UTF-16...) or just ASCII, depending on your locale (check LC_CTYPE on Unix or GNU).

As a convenience (because you may want to deal with non-ASCII content in your -e source), your code is converted from bytes using the current locale.

dolmen@github 1 comment

XKPasswd A secure memorable password generator

A secure memorable password generator inspired by the wonderful XKCD webcomic at http://www.xkcd.com/ and Steve Gibson's Password Haystacks page at https://www.grc.com/haystack.htm. This is the Perl library that powers https://www.xkpasswd.net.

bbusschots@github 6 comments

DBIx::Class::Schema::Loader::DBI::RelPatterns Relationship patterns for DBIx::Class::Schema::Loader

DESCRIPTION

DBIx::Class::Schema::Loader::DBI::RelPatterns is a pseudo loader class that provides the means to set up the table relationships when DBIx::Class::Schema::Loader fails to for any reason. It was designed with MySQL's MyISAM storage engine in mind but should work correctly with pretty much any DBI driver that:

Unlike conventional loader classes, DBIx::Class::Schema::Loader::DBI::RelPatterns allows DBIx::Class::Schema::Loader::DBI to load a driver-specific class, then extends it and wraps some of its methods (hence the word "pseudo"), adding to the mix the relationship patterns, user-definable via "rel_constraint" and "rel_exclude" options (which are added to the base options of DBIx::Class::Schema::Loader). If "rel_constraint" option is not specified, DBIx::Class::Schema::Loader::DBI::RelPatterns becomes a no-op, passing through to the driver-specific class. Otherwise it helps to set up the relationships whenever corresponding columns in the referencing key and the referenced key meet all of the following conditions:

  • they match any of the rel_constraint patterns;
  • they match none of the rel_exclude patterns;
  • they have exactly the same or similar data types.

In general, the columns also have to be indexed. However, rel_constraint patterns allow one to explicitly specify that being indexed is not obligatory. This seems like a bad idea, but you may want to (or even have to) do this if the DBI driver in use does not support statistics_info method, which is required to obtain the non-unique index information (which is useless to DBIx::Class but can help to avoid the false-positive rel_constraint pattern matches when patterns are not specific enough). Although in such a case the composite key relationships will be left out, thus limiting the resulting DBIx::Class schema to just simple key relationships.

When multiple columns in the referenced table meet the conditions, preference is given - in order of priority - to column that is listed in:

  • primary key;
  • unique key;
  • single-column index;
  • composite index as the first column or closer to the first column;
  • smallest composite index.

By design, all determined relationships are considered to be simple key relationships. However, when multiple relationships between two tables are identified, and columns of these relationships are listed in the corresponding composite indexes as the first columns (i.e., they form the leftmost prefixes), then a composite key relationship is set up instead of multiple simple key ones.

Note that rel_constraint and rel_exclude patterns do not affect the relationships that DBIx::Class::Schema::Loader is able to identify unaided. That is, DBIx::Class::Schema::Loader::DBI::RelPatterns helps to add missing relationships but not alter or remove the ones already identified.

ADDED CONSTRUCTOR OPTIONS

rel_constraint

Specifies the relationship patterns between any two tables. Table relationship is set up only if its condition matches any of the specified patterns.

This option takes an arrayref with even number of elements (like in a hashref). Every odd element (a key) refers to the referencing table, while every even element (a value) refers to the table being referenced. Elements can be strings, qr// regexps or hashrefs.

Simplified syntax:

    rel_constraint => [
            # column foo_id in table bars references column id in table foos
            'bars.foo_id' => 'foos.id',

            # column foo_id in any table references primary key in table foos
            'foo_id' => 'foos.',

            # column (.+)_id in any table references primary key in table ${1}s
            # e.g. foo_id => foos.id, bar_id => bars.id, baz_id => bazs.id etc.
            qr/(.+)_id$/i => qr/(.+)s$/i,
    ]

Strings and qr// regexps actually are shortcuts to the hashrefs:

    rel_constraint => [
            'bar.foo_id' => 'db1.foos.id', #hashref equivalents below
            { tab=>'bar', col=>'foo_id' } => { sch=>'db1', tab=>'foos', col=>'id' },

            'foo_id' => 'foos.id', #hashref equivalents below
            { col=>'foo_id' } => { tab=>'foos', col=>'id' },

            qr/(.*?)s?_?id$/i => qr/(.*?)s?$/i, #hashref equivalents below
            { col=>qr/(.*?)s?_?id$/i } => { tab=>qr/(.*?)s?$/i },
    ]

If element is a string in "schema.table.column" format, then it gets split from right to left into column name, table name and schema name. That is, 'foo' would be column, 'bar.' would be table, 'baz..' would be schema.

If elements are qr// regexps, then the key (pattern's left-hand side) refers to the referencing column name, while the value (pattern's right-hand side) refers to the referenced table name.

If element is not a shortcut but a hashref, then it can have the following keys:

  • sch

    Schema name; string or qr// regexp.

  • tab

    Table name; string or qr// regexp.

  • col

    Column name; string or qr// regexp.

  • index

    Index type. Accepted values:

    • 'primary' - match only primary keys;
    • 'unique' - match unique keys as well;
    • 'any' (the default) - match also non-unique indexes;
    • 'optional' (forced when "tab" and "col" are non-empty strings) - match everything, including columns that are not indexed.
  • type

    Level of similarity between column data types; applies to pattern's right-hand side. Accepted values:

    • 'similar' - ignore the size of column data types with size restriction (e.g., allow varchar(10) to reference varchar(15));
    • 'exact' (the default) - require the size to match as well.

"sch", "index" and "type" defaults can be adjusted by omitting "tab" and "col". The following two are equivalent:

    rel_constraint => [
            # specify sch, index and type explicitly, without touching the defaults
            { sch=>'db1', col=>qr/(.*?)s?_?id$/i, index=>'optional' }
                    => { sch=>'db1', tab=>qr/(.*?)s?$/i, index=>'unique', type=>'similar' },
    ]

    rel_constraint => [
            # adjust the defaults first
            'db1..' => 'db1..',
            { index=>'optional' } => { index=>'unique', type=>'similar' },
            # the adjusted defaults are applied to all patterns below
            qr/(.*?)s?_?id$/i => qr/(.*?)s?$/i,
    ]

Note that self-referential relationships are set up only if "tab" is specified on both sides of the relationship pattern:

    rel_constraint => [
            # self-referential relationship (tab on both sides)
            'foos.foo_id' => 'foos.id',

            # not including self-referential relationships;
            # i.e. does not imply the relationship above
            'foo_id' => 'foos.id',

            # self-referential relationships (tab on both sides)
            { tab=>qr/(.+)s$/i, col=>qr/(.+)_id$/i }
                    => { tab=>qr/(.+)s$/i, col=>'id' },

            # not including self-referential relationships;
            # i.e. does not imply the relationships above
            { col=>qr/(.+)_id$/i } => { tab=>qr/(.+)s$/i, col=>'id' },
    ]

If qr// regexp creates capture groups, then the relationship is set up only when the captured contents of each regular expression within the given relationship pattern do match. For example, the following relationship pattern references column (foo|bar|baz)_id with column ${1}id in table ${1}s:

    rel_constraint => [
            { col=>qr/^(foo|bar|baz)_id$/ }
                    => { tab=>qr/^(foo|bar|baz)s$/, col=>qr/^(foo|bar|baz)id$/ },
    ]

Readable equivalent:

    rel_constraint => [
            'foo_id' => 'foos.fooid',
            'bar_id' => 'bars.barid',
            'baz_id' => 'bazs.bazid',
    ]

Generic version:

    rel_constraint => [
            qr/(.+)_id$/i => { tab=>qr/(.+)s$/i, col=>qr/(.+)id$/i },
    ]

rel_exclude

Specifies the relationship pattern exclusions. Table relationship is set up only if its condition matches none of the specified patterns.

The syntax is borrowed from "rel_constraint"; however only "sch", "tab", "col" keys in hashref elements are supported, and default "sch" cannot be set.

    rel_exclude => [
            # column foo_id in any table should not reference column id in table foos
            'foo_id' => 'foos.id',

            # column (.+)_id in any table should not reference column id in table ${1}s
            qr/(.+)_id$/ => { tab=>qr/(.+)s$/, col=>'id' },

            # any column in table baz should not reference anything
            'baz.' => '',

            # any column in tables like 'foo%' should not reference anything
            { tab=>qr/^foo/ } => '',

            # anything in schema db1 should not reference anything in schema db2
            'db1..' => 'db2..',
    ]

azlewa@github 0 comments

Code::MFF Multi Flip-Flop - emulate flip-flop operator with more than 2 states

Experimental work in progress.

Works like the "3 dot" flip-flop operator ( ... ) with additional states and corresponding triggers. There is a trigger condition for each of an arbitrary number of active states, and a final trigger to reset to the inactive state.

Self test included:

while () {
chomp;
mff(qr/alpha/ => \&_s1,
    qr/beta/  => \&_s2,
    \&_c3     => \&_s3,
    +_c4()            ) or print "*:$_\n";
}

Expected results:

Evaluating condition 4
*:This is
Evaluating condition 4
1:the alpha
Evaluating condition 4
1:but not
Evaluating condition 4
1:the omega
Evaluating condition 4
2:Now the beta
Evaluating condition 4
Evaluating condition 3
2:progressing to
Evaluating condition 4
Evaluating condition 3
3:the gamma
Evaluating condition 4
3:and finally
Evaluating condition 4
*:the omega
Evaluating condition 4
*:Did this work?

Notes in the pod documentation (attempt to) explain why this is the expected output.

ronww@github 0 comments

Log::Redirect Log messages to a file by redirecting STDOUT or STDERR

A perl module that redirects output log messages into specific log files using simply the print()',printf()', and warn()' built-in Perl sub-routines. The interface allows a programmer to simply write the messages he wants to produce usingprint()', printf' orwarn', and let a different portion of the code take care of where it gets written to. This has a couple of advantages:

1. It allows the program to be independent of the names for the
logfiles, and allows the user to choose his names
2. It is very easy to make a message appear on screen as well as in a
file, without repeating the print statement - this is done using the
`verbose' option.
3. No special logging functions need to be used. The standard `print',
`printf' and `warn' functions do the job.
4. Works correctly even if used with `fork()'.

RATIONALE

Writing logs have become exceedingly hard, when in reality it is a
rather simple task: tell the user what is going on. Most modules allow
one to write log messages with message levels and stuff. But sometimes
they are not useful, and sometimes the modules just do not cover all the
message levels that one may want. The end result is that a programmer
has to take special care to choose a good logging interface and that
takes time away from his core work - writing the algorithm.

`Log::Redirect' allows a programmer to think of the algorithm first, and
log messages later. It also allows for a very easy way to display the
log on screen and simultaneously writing to the file. `Log::Redirect'
also writes to the disk instantly and doesn't wait for the buffer to be
full before it begins writing something.

METHODS

new

Creates a new object of this class. It requires a filename as a required
argument. In addition, it can accept an optional parameter

        my $mylog = Log::Redirect->new('mylog.log');
        my $verboselog = Log::Redirect->new('verbose.log', verbose => 1);

EXPORT

None by default.

balajirama@github 2 comments

DBIx::Class::Factory Factory-style fixtures for DBIx::Class

I try to create factory_girl/factory_boy analogue for Perl.

I would be happy to name it Test::DBIx::Class::Factory (since my module is mostly intended for tests) but this name is occupied.

This is my first destribution and I messed up a little with version numbers, don't look at that :).

What should I improve?

Thanks!

Also see project on github.

VadimPushtaev@github 0 comments

Data::Transit Implementation of the transit format in perl

Transit is a format layered on top of JSON and MessagePack which encodes the type into the data being sent. This library provides support for converting to/from Transit in Perl. If you want information on the format in general, you can get that at https://github.com/cognitect/transit-format.

lackita@github 6 comments

MooX::Cmd::ChainedOptions Easy access to options up the chain of commands

When used instead of MooX::Options in applications constructed with MooX::Cmd, this class adds attributes to a command object which provide access to command line options passed to commands higher up the command chain.

For example (using the above code which creates an application and a command), the following command line

app --app-opt=FOO cmd --cmd-opt=BAR

would result in the MyApp::Cmd::cmd object having an attribute called app_opt which contains FOO.

Without this module, the MyApp::Cmd::cmd object would have to search through the chain of commands (passed to the execute method, or available via the command_chainmethod)looking for the app_opt attribute.

I'm afraid the name may be confused with "chained" method approaches, but MooX::Cmd uses the "chain" terminology to describe the hierarchy of commands, so I thought I'd stick to that.

Any alternate suggestions?

Thanks, Diab

djerius@github 0 comments

Net::Amazon::IAM Perl interface to the Amazon Identity and Access Management.

Looked for same module and didn't found any.

I was needed it in order to accomplish some tasks for my job.

I used php temporary since there was nothing similar in perl.

It still not fully done, not all methods allowed by API were implemented, but basic functionality is here, tested and found working.

By next steps I'm going to implement some tests and add other functionality available in API.

tsiganenok@github 1 comment

WWW::Mech restructuration of the WWW::Mechanize ecosystem

I use the WWW::Mechanize::* and Test::Mechanize::* modules quite a lot, but they have the problem that they all pretty do their own things and don't aggregate cleanly. For example, I recently wanted to use Test::WWW::Mechanize::JSON with Test::WWW::Mechanize::PSGI. I ended monkey-patching the wanted methods of the former in the latter. Worked fine, but feels icky.

So what I would like to try to come up with a modular design for all things WWW::Mechanize. I'm thinking of the following:

Split the functionality of WWW::Mechanize between two main area: the agent, which job is solely to take the requests and give back responses, and the plugins, which do things to those responses/requests.

So the creation of a $mech object will be along the lines of

my $mech = WWW::Mech->new(
    agent => 'WWW::Mech::Agent::PSGI',
    plugins => [ 
        'WWW::Mech::Plugin::Test',  # brings in get_ok, content_is, etc
        'WWW::Mech::Plugin::JSON',  #  brings in json_ok and friends
    ],
);

$mech->get_ok( 'http://localhost' );
$mech->json_ok;

In the same vein, I'd also make it possible to have a $mech singleton so that, for quick tests, one can do away with the $mech-> bit

WWW::Mech->singleton(
    agent => 'WWW::Mech::Agent::PSGI',
    plugins => [ 
        'WWW::Mech::Plugin::Test',  # brings in get_ok, content_is, etc
        'WWW::Mech::Plugin::JSON',  #  brings in json_ok and friends
    ],
);

get_ok 'http://localhost';
json_ok;

So... sounds something worth exploring?

yanick@github 2 comments