Vincent Pit >
Sub-Nary >
Sub::Nary

Module Version: 0.03
Sub::Nary - Try to count how many elements a subroutine can return in list context.

Version 0.03

use Sub::Nary; my $sn = Sub::Nary->new(); my $r = $sn->nary(\&hlagh);

This module uses the B framework to walk into subroutines and try to guess how many scalars are likely to be returned in list context. It's not always possible to give a definitive answer to this question at compile time, so the results are given in terms of "probability of return" (to be understood in a sense described below).

`new`

The usual constructor. Currently takes no argument.

`nary $coderef`

Takes a code reference to a named or anonymous subroutine, and returns a hash reference whose keys are the possible numbers of returning scalars, and the corresponding values the "probability" to get them. The special key `'list'`

is used to denote a possibly infinite number of returned arguments. The return value hence would look at

{ 1 => 0.2, 2 => 0.4, 4 => 0.3, list => 0.1 }

that is, we should get `1`

scalar `1`

time over `5`

and so on. The sum of all values is `1`

. The returned result, and all the results obtained from intermediate subs, are cached into the object.

`flush`

Flushes the Sub::Nary object cache. Returns the object itself.

The probability is computed as such :

- When branching, each branch is considered equally possible.
For example, the subroutine

sub simple { if (rand < 0.1) { return 1; } else { return 2, 3; } }

is seen returning one or two arguments each with probability

`1/2`

. As forsub hlagh { my $x = rand; if ($x < 0.1) { return 1, 2, 3; } elsif ($x > 0.9) { return 4, 5; } }

it is considered to return

`3`

scalars with probability`1/2`

,`2`

with probability`1/2 * 1/2 = 1/4`

and`1`

(when the two tests fail, the last computed value is returned, which here is`$x > 0.9`

evaluated in the scalar context of the test) with remaining probability`1/4`

. - The total probability law for a given returning point is the convolution product of the probabilities of its list elements.
As such,

sub notsosimple { return 1, simple(), 2 }

returns

`3`

or`4`

arguments with probability`1/2`

; andsub double { return simple(), simple() }

never returns

`1`

argument but returns`2`

with probability`1/2 * 1/2 = 1/4`

,`3`

with probability`1/2 * 1/2 + 1/2 * 1/2 = 1/2`

and`4`

with probability`1/4`

too. - If a core function may return different numbers of scalars, each kind is considered equally possible.
For example,

`stat`

returns`13`

elements on success and`0`

on error. The according probability will then be`{ 0 => 0.5, 13 => 0.5 }`

. - The
`list`

state is absorbing in regard of all the other ones.This is just a pedantic way to say that "list + fixed length = list". That's why

sub listy { return 1, simple(), @_ }

is considered as always returning an unbounded list.

Also, the convolution law does not behave the same when

`list`

elements are involved : in the following example,sub oneorlist { if (rand < 0.1) { return 1 } else { return @_ } } sub composed { return oneorlist(), oneorlist() }

`composed`

returns`2`

scalars with probability`1/2 * 1/2 = 1/4`

and a`list`

with probability`3/4`

.

An object-oriented module shouldn't export any function, and so does this one.

The algorithm may be pessimistic (things seen as `list`

while they are of fixed length) but not optimistic (the opposite, duh).

`wantarray`

isn't specialized when encountered in the optree.

perl 5.8.1.

Carp (standard since perl 5), B (since perl 5.005) and XSLoader (since perl 5.006).

Vincent Pit, `<perl at profvince.com>`

, http://www.profvince.com.

You can contact me by mail or on #perl @ FreeNode (vincent or Prof_Vince).

Please report any bugs or feature requests to `bug-b-nary at rt.cpan.org`

, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Sub-Nary. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

You can find documentation for this module with the perldoc command.

perldoc Sub::Nary

Tests code coverage report is available at http://www.profvince.com/perl/cover/Sub-Nary.

Thanks to Sebastien Aperghis-Tramoni for helping to name this module.

Copyright 2008 Vincent Pit, all rights reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

syntax highlighting: