NAME
Hades - Less is more, more is less!
VERSION
Version 0.23
SYNOPSIS
use
Hades;
Hades->run({
eval
=>
q|
Kosmos {
[penthos curae] :t(Int) :d(2) :p :pr :c :r
geras $nosoi :t(Int) :d(2) {
if (£penthos == $nosoi) {
return £curae;
}
}
}
|
});
... generates ...
package
Kosmos;
use
strict;
use
warnings;
our
$VERSION
= 0.01;
sub
new {
my
(
$cls
,
%args
) = (
shift
(),
scalar
@_
== 1 ? %{
$_
[0] } :
@_
);
my
$self
=
bless
{},
$cls
;
my
%accessors
= (
penthos
=> {
required
=> 1,
default
=> 2, },
curae
=> {
required
=> 1,
default
=> 2, },
);
for
my
$accessor
(
keys
%accessors
) {
my
$value
=
$self
->
$accessor
(
defined
$args
{
$accessor
}
?
$args
{
$accessor
}
:
$accessors
{
$accessor
}->{
default
} );
unless
( !
$accessors
{
$accessor
}->{required} ||
defined
$value
) {
die
"$accessor accessor is required"
;
}
}
return
$self
;
}
sub
penthos {
my
(
$self
,
$value
) =
@_
;
my
$private_caller
=
caller
();
if
(
$private_caller
ne __PACKAGE__ ) {
die
"cannot call private method penthos from $private_caller"
;
}
if
(
defined
$value
) {
if
(
ref
$value
||
$value
!~ m/^[-+\d]\d*$/ ) {
die
qq{Int: invalid value $value for accessor penthos}
;
}
$self
->{penthos} =
$value
;
}
return
$self
->{penthos};
}
sub
clear_penthos {
my
(
$self
) =
@_
;
delete
$self
->{penthos};
return
$self
;
}
sub
has_penthos {
my
(
$self
) =
@_
;
return
exists
$self
->{penthos};
}
sub
curae {
my
(
$self
,
$value
) =
@_
;
my
$private_caller
=
caller
();
if
(
$private_caller
ne __PACKAGE__ ) {
die
"cannot call private method curae from $private_caller"
;
}
if
(
defined
$value
) {
if
(
ref
$value
||
$value
!~ m/^[-+\d]\d*$/ ) {
die
qq{Int: invalid value $value for accessor curae}
;
}
$self
->{curae} =
$value
;
}
return
$self
->{curae};
}
sub
clear_curae {
my
(
$self
) =
@_
;
delete
$self
->{curae};
return
$self
;
}
sub
has_curae {
my
(
$self
) =
@_
;
return
exists
$self
->{curae};
}
sub
geras {
my
(
$self
,
$nosoi
) =
@_
;
$nosoi
=
defined
$nosoi
?
$nosoi
: 5;
if
( !
defined
(
$nosoi
) ||
ref
$nosoi
||
$nosoi
!~ m/^[-+\d]\d*$/ ) {
$nosoi
=
defined
$nosoi
?
$nosoi
:
'undef'
;
die
qq{Int: invalid value $nosoi for variable \$nosoi in method geras}
;
}
if
(
$self
->penthos ==
$nosoi
) {
return
$self
->curae; }
}
1;
__END__
SUBROUTINES/METHODS
run
- file
-
Provide a file to read in.
- eval
-
Provide a string to eval.
- verbose
-
Set verbose to true, to print build steps to STDOUT.
- debug
-
Set debug to true, to step through the build.
- dist
-
Provide a name for the distribution.
- lib
-
Provide a path where the generated files will be compiled.
- tlib
-
Provide a path where the generates test files will be compiled.
-
The author of the distribution/module.
-
The authors email of the distribution/module.
- version
-
The version number of the distribution/module.
- realm
-
The Hades realm that is used to generate the code.
Hades
Class
Declare a new class.
Kosmos {
}
Abstract
Declare the classes Abstract.
Kosmos {
abstract { Afti einai i perilipsi }
}
Synopsis
Declare the classes Synopsis.
Kosmos {
synopsis {
Schetika me ton Kosmos
Kosmos->new;
}
}
Inheritance
base
Establish an ISA relationship with base classes at compile time.
Unless you are using the fields pragma, consider this discouraged in favor of the lighter-weight parent.
Kosmos base Kato {
}
parent
Establish an ISA relationship with base classes at compile time.
Kosmos parent Kato {
}
require
Require library files to be included if they have not already been included.
}
use
Declare modules that should be included in the class.
}
Test
Declare the classes additional tests.
Kosmos {
test {
[
[
'ok'
,
'my $obj = Kosmos->new'
],
[
'is'
,
'$obj->dokimi'
,
undef
]
]
}
}
Compile phase
begin
Define a code block is executed as soon as possible.
Kosmos {
begin {
... perl code ...
}
}
unitcheck
Define a code block that is executed just after the unit which defined them has been compiled.
Kosmos {
unitcheck {
... perl code ...
}
}
check
Define a code block that is executed just after the initial Perl compile phase ends and before the run time begins.
Kosmos {
check {
... perl code ...
}
}
init
Define a code block that is executed just before the Perl runtime begins execution.
Kosmos {
init {
... perl code ...
}
}
end
Define a code block is executed as late as possible.
Kosmos {
end {
... perl code ...
}
}
Variables
our
Declare variable of the same name in the current package for use within the lexical scope.
Kosmos {
our
$one
%two
}
Accessors
Declare an accessor for the class
Kosmos {
dokimi
dokimes
}
:required | :r
Making an accessor required means a value for the accessor must be supplied to the constructor.
dokimi :r
dokimes :required
:default | :d
The default is used when no value for the accessor was supplied to the constructor.
dokimi :d(Eimai o monos)
dokimes :
default
([{
ola
=>
"peripou"
,
o
=> [
qw/kosmos/
] }])
:clearer | :c
Setting clearer creates a method to clear the accessor.
dokimi :c
dokimes :clearer
$class
->clear_dokimi;
:coerce | :co
Takes a coderef which is meant to coerce the attributes value.
dokimi :co(array_to_string)
dokimes :coerce(
$value
=
$value
->[0]
if
ref
(
$value
) ||
""
eq
"ARRAY"
;)
:private | :p
Setting private makes the accessor only available to the class.
dokimi :p
dokimes :private
:predicate | :pr
Takes a method name which will return true if an attribute has a value. The predicate is automatically named has_${accessor}.
dokimi :pr
dokimes :predicate
:trigger | :tr
Takes a coderef which will get called any time the attribute is set.
dokimi :
tr
(trigger_to_method)
dokimes :trigger(
warn
Dumper
$value
)
:type | :t
Add type checking to the accessor.
dokimi :t(Dict[
onoma
=> Str,
id
=> Optional[Int],
epiloges
=> Dict[
onama
=> Str]])
dokimes :type(Str)
:builder | :bdr
Takes a coderef which is meant to build the attributes value.
dokimi :bdr
dokimes :builder(
$value
=
$value
->[0]
if
ref
(
$value
) ||
""
eq
"ARRAY"
;)
:test | :z
Add tests associated to the accessor.
dokimi :z([
'ok'
,
'$obj->dokimi'
])
dokimes :z([
'deep'
,
'$obj->dokimes({})'
,
q|{}|
)
Methods
Declare a sub routine/method.
Kosmos {
dokimi {
... perl code ...
}
}
Params
Methods will always have $self defined but you can define additional params by declaring them before the code block.
dokimi
$one
%two
{
... perl code ...
}
generates
sub
dokimi {
my
(
$self
,
$one
,
%two
) =
@_
;
... perl code ...
}
:type :t
Add type checking to the param.
dokimi
$one
:t(Str) {
... perl code ...
}
dokimes
$one
:t(Str)
$two
:t(HashRef) {
... perl code ...
}
:coerce | :co
Takes a coderef which is meant to coerce the method param.
dokimi
$str
:co(array_to_string)
dokimes
$str
:t(Str) :co(array_to_string)
:private :p
Setting private makes the method only available to the class.
dokimi :p {
... perl code ...
}
dokimes :private
$one
%two
{
... perl code ...
}
:default | :d
The default is used when no value for the sub was passed as a param.
dokimi
$str
:d(Eimai o monos) { }
dokimes
$arrayRef
:
default
([{
ola
=>
"peripou"
,
o
=> [
qw/kosmos/
] }]) { }
:test | :z
Add tests associated to the sub.
dokimi :z([
'ok'
,
'$obj->dokimi'
]) { }
dokimes :test([
'deep'
,
'$obj->dokimes({})'
,
q|{}|
) { }
:before | :b
Before is called before the parent method is called. You can modify the params using the @params variable.
dokimi :b {
...
before
...
}:
generates
sub
dokimi {
my
(
$orig
,
$self
,
@params
) = (
'SUPER::geras'
,
@_
);
...
before
...
my
@res
=
$self
->
$orig
(
@params
);
return
@res
;
}
:around | :ar
Around is called instead of the method it is modifying. The method you're overriding is passed in as the first argument (called $orig by convention). You can modify the params using the @params variable.
dokimi :ar {
...
before
around
...
my
@res
=
$self
->
$orig
(
@params
);
...
after
around
...
}
generates
sub
dokimi {
my
(
$orig
,
$self
,
@params
) = (
'SUPER::geras'
,
@_
);
...
before
around
...
my
@res
=
$self
->
$orig
(
@params
);
...
after
around
...
return
@res
;
}
:after | :a
After is called after the parent method is called. You can modify the response using the @res variable.
dokimi :a {
...
after
...
}
generates
sub
dokimi {
my
(
$orig
,
$self
,
@params
) = (
'SUPER::geras'
,
@_
);
my
@res
=
$self
->
$orig
(
@params
);
...
after
...
return
@res
;
}
Types
Any
Absolutely any value passes this type constraint (even undef).
dokimi :t(Any)
Item
Essentially the same as Any. All other type constraints in this library inherit directly or indirectly from Item.
dokimi :t(Item)
Bool
Values that are reasonable booleans. Accepts 1, 0, the empty string and undef.
dokimi :t(Bool)
Str
Any string.
dokimi :t(Str)
Num
Any number.
dokimi :t(Num)
Int
An integer; that is a string of digits 0 to 9, optionally prefixed with a hyphen-minus character.
dokimi :t(Int)
Ref
Any defined reference value, including blessed objects.
dokimi :t(Ref)
dokimes :t(Ref[HASH])
ScalarRef
A value where ref($value) eq "SCALAR" or ref($value) eq "REF".
dokimi :t(ScalarRef)
dokimes :t(ScalarRef[SCALAR])
ArrayRef
A value where ref($value) eq "ARRAY".
dokimi :t(ArrayRef)
dokimes :t(ArrayRef[Str, 1, 100])
HashRef
A value where ref($value) eq "HASH".
dokimi :t(HashRef)
dokimes :t(HashRef[Int])
CodeRef
A value where ref($value) eq "CODE"
dokimi :t(CodeRef)
RegexpRef
A value where ref($value) eq "Regexp"
dokimi :t(RegexpRef)
GlobRef
A value where ref($value) eq "GLOB"
dokimi :t(GlobRef)
Object
A blessed object.
dokimi :t(Object)
Map
Similar to HashRef but parameterized with type constraints for both the key and value. The constraint for keys would typically be a subtype of Str.
dokimi :t(Map[Str, Int])
Tuple
Accepting a list of type constraints for each slot in the array.
dokimi :t(Tuple[Str, Int, HashRef])
Dict
Accepting a list of type constraints for each slot in the hash.
dokimi :t(Dict[
onoma
=> Str,
id
=> Optional[Int],
epiloges
=> Dict[
onama
=> Str]])
Optional
Used in conjunction with Dict and Tuple to specify slots that are optional and may be omitted.
dokimi :t(Optional[Str])
Macros
Hades has a concept of macros that allow you to write re-usable code. see https://metacpan.org/source/LNATION/Hades-0.23/macro-fh.hades for an example of how to extend via macros.
macro {
FH [
macro
=> [
qw/read_file write_file/
],
alias
=> {
read_file
=> [
qw/rf/
],
write_file
=> [
qw/wf/
] } ]
str2ArrayRef :a(s2ar) {
return
qq|$params[0] = [ $params[0] ];|
;
}
ArrayRef2Str :a(ar2s) {
return
qq|$params[0] = $params[0]\->[0];|
;
}
}
MacroKosmos {
eros
$eros
:t(Str) :d(t/test.txt) {
€s2ar(
'$eros'
);
€ar2s(
'$eros'
);
€wf(
'$eros'
,
q|'this is a test'|
);
return
$eros
;
}
psyche
$psyche
:t(Str) :d(t/test.txt) {
€rf(
'$psyche'
);
return
$content
;
}
}
... generates ...
package
MacroKosmos;
use
strict;
use
warnings;
our
$VERSION
= 0.01;
sub
new {
my
(
$cls
,
%args
) = (
shift
(),
scalar
@_
== 1 ? %{
$_
[0] } :
@_
);
my
$self
=
bless
{},
$cls
;
my
%accessors
= ();
for
my
$accessor
(
keys
%accessors
) {
my
$value
=
$self
->
$accessor
(
defined
$args
{
$accessor
}
?
$args
{
$accessor
}
:
$accessors
{
$accessor
}->{
default
} );
unless
( !
$accessors
{
$accessor
}->{required} ||
defined
$value
) {
die
"$accessor accessor is required"
;
}
}
return
$self
;
}
sub
eros {
my
(
$self
,
$eros
) =
@_
;
$eros
=
defined
$eros
?
$eros
:
"t/test.txt"
;
if
( !
defined
(
$eros
) ||
ref
$eros
) {
$eros
=
defined
$eros
?
$eros
:
'undef'
;
die
qq{Str: invalid value $eros for variable \$eros in method eros}
;
}
$eros
= [
$eros
];
$eros
=
$eros
->[0];
open
my
$wh
,
">"
,
$eros
or
die
"cannot open file for writing: $!"
;
$wh
'this is a test'
;
close
$wh
;
return
$eros
;
}
sub
psyche {
my
(
$self
,
$psyche
) =
@_
;
$psyche
=
defined
$psyche
?
$psyche
:
"t/test.txt"
;
if
( !
defined
(
$psyche
) ||
ref
$psyche
) {
$psyche
=
defined
$psyche
?
$psyche
:
'undef'
;
die
qq{Str: invalid value $psyche for variable \$psyche in method psyche}
;
}
open
my
$fh
,
"<"
,
$psyche
or
die
"cannot open file for reading: $!"
;
my
$content
=
do
{
local
$/; <
$fh
> };
close
$fh
;
return
$content
;
}
1;
__END__
Testing
Hades can auto-generate test files. If you take the following example:
use
Hades;
Hades->run({
eval
=>
q|Dokimes {
curae :r :default(5)
penthos :t(Str) :r
nosoi :default(3) :t(Int) :clearer
limos
$test :t(Str)
:test(
['ok', '$obj->penthos(2) && $obj->nosoi(2) && $obj->curae(5)'],
['is', '$obj->limos("yay")', 5 ],
['ok', '$obj->penthos(5)' ],
['is', '$obj->limos("yay")', q{''}]
)
{ if ($_[0]->penthos == $_[0]->nosoi) { return $_[0]->curae; } }
}|
,
lib
=>
'lib'
,
tlib
=>
't/lib'
,
});
It will generate a test file located at t/lib/Dokimes.t which looks like:
use
Test::More;
use
strict;
use
warnings;
BEGIN { use_ok(
'Dokimes'
); }
subtest
'new'
=>
sub
{
plan
tests
=> 16;
ok(
my
$obj
= Dokimes->new( {
curae
=>
'hypnos'
,
penthos
=>
'aporia'
} ),
q{my $obj = Dokimes->new({curae => 'hypnos', penthos => 'aporia'}
)}
);
ok(
$obj
= Dokimes->new(
curae
=>
'hypnos'
,
penthos
=>
'aporia'
),
q{$obj = Dokimes->new(curae => 'hypnos', penthos => 'aporia')}
);
isa_ok(
$obj
,
'Dokimes'
);
ok(
$obj
= Dokimes->new( {
penthos
=>
'aporia'
,
nosoi
=> 10 } ),
q{$obj = Dokimes->new({penthos => 'aporia', nosoi => 10}
)}
);
ok(
$obj
= Dokimes->new(
penthos
=>
'aporia'
,
nosoi
=> 10 ),
q{$obj = Dokimes->new(penthos => 'aporia', nosoi => 10)}
);
is(
$obj
->curae, 5,
q{$obj->curae}
);
ok(
$obj
= Dokimes->new(
{
curae
=>
'hypnos'
,
penthos
=>
'aporia'
,
nosoi
=> 10 }
),
q{$obj = Dokimes->new({ curae => 'hypnos', penthos => 'aporia', nosoi => 10 }
)}
);
eval
{
$obj
= Dokimes->new( {
curae
=>
'hypnos'
,
nosoi
=> 10 } ) };
like( $@,
qr/required/
,
q{$obj = Dokimes->new({curae => 'hypnos', nosoi => 10}
)} );
eval
{
$obj
= Dokimes->new(
{
curae
=>
'hypnos'
,
penthos
=> [],
nosoi
=> 10 } );
};
like(
$@,
qr/invalid value|greater|atleast/
,
q{$obj = Dokimes->new({ curae => 'hypnos', penthos => [], nosoi => 10 }
)}
);
eval
{
$obj
= Dokimes->new(
{
curae
=>
'hypnos'
,
penthos
=> \1,
nosoi
=> 10 } );
};
like(
$@,
qr/invalid value|greater|atleast/
,
q{$obj = Dokimes->new({ curae => 'hypnos', penthos => \1, nosoi => 10 }
)}
);
eval
{
$obj
= Dokimes->new(
{
curae
=>
'hypnos'
,
penthos
=>
''
,
nosoi
=> 10 } );
};
like(
$@,
qr/invalid value|greater|atleast/
,
q{$obj = Dokimes->new({ curae => 'hypnos', penthos => '', nosoi => 10 }
)}
);
ok(
$obj
= Dokimes->new( {
curae
=>
'hypnos'
,
penthos
=>
'aporia'
} ),
q{$obj = Dokimes->new({curae => 'hypnos', penthos => 'aporia'}
)}
);
ok(
$obj
= Dokimes->new(
curae
=>
'hypnos'
,
penthos
=>
'aporia'
),
q{$obj = Dokimes->new(curae => 'hypnos', penthos => 'aporia')}
);
is(
$obj
->nosoi, 3,
q{$obj->nosoi}
);
eval
{
$obj
= Dokimes->new(
{
curae
=>
'hypnos'
,
penthos
=>
'aporia'
,
nosoi
=> [] } );
};
like(
$@,
qr/invalid value|greater|atleast/
,
q{$obj = Dokimes->new({ curae => 'hypnos', penthos => 'aporia', nosoi => [] }
)}
);
eval
{
$obj
= Dokimes->new(
{
curae
=>
'hypnos'
,
penthos
=>
'aporia'
,
nosoi
=>
'limos'
} );
};
like(
$@,
qr/invalid value|greater|atleast/
,
q{$obj = Dokimes->new({ curae => 'hypnos', penthos => 'aporia', nosoi => 'limos' }
)}
);
};
subtest
'curae'
=>
sub
{
plan
tests
=> 2;
ok(
my
$obj
= Dokimes->new( {
curae
=>
'hypnos'
,
penthos
=>
'aporia'
} ),
q{my $obj = Dokimes->new({curae => 'hypnos', penthos => 'aporia'}
)}
);
can_ok(
$obj
,
'curae'
);
};
subtest
'penthos'
=>
sub
{
plan
tests
=> 7;
ok(
my
$obj
= Dokimes->new( {
curae
=>
'hypnos'
,
penthos
=>
'aporia'
} ),
q{my $obj = Dokimes->new({curae => 'hypnos', penthos => 'aporia'}
)}
);
can_ok(
$obj
,
'penthos'
);
is_deeply(
$obj
->penthos(
'curae'
),
'curae'
,
q{$obj->penthos('curae')}
);
eval
{
$obj
->penthos( [] ) };
like( $@,
qr/invalid value|greater|atleast/
,
q{$obj->penthos([])}
);
eval
{
$obj
->penthos( \1 ) };
like( $@,
qr/invalid value|greater|atleast/
,
q{$obj->penthos(\1)}
);
eval
{
$obj
->penthos(
''
) };
like( $@,
qr/invalid value|greater|atleast/
,
q{$obj->penthos('')}
);
is_deeply(
$obj
->penthos,
'curae'
,
q{$obj->penthos}
);
};
subtest
'nosoi'
=>
sub
{
plan
tests
=> 6;
ok(
my
$obj
= Dokimes->new( {
curae
=>
'hypnos'
,
penthos
=>
'aporia'
} ),
q{my $obj = Dokimes->new({curae => 'hypnos', penthos => 'aporia'}
)}
);
can_ok(
$obj
,
'nosoi'
);
is_deeply(
$obj
->nosoi(10), 10,
q{$obj->nosoi(10)}
);
eval
{
$obj
->nosoi( [] ) };
like( $@,
qr/invalid value|greater|atleast/
,
q{$obj->nosoi([])}
);
eval
{
$obj
->nosoi(
'phobos'
) };
like( $@,
qr/invalid value|greater|atleast/
,
q{$obj->nosoi('phobos')}
);
is_deeply(
$obj
->nosoi, 10,
q{$obj->nosoi}
);
};
subtest
'limos'
=>
sub
{
plan
tests
=> 10;
ok(
my
$obj
= Dokimes->new( {
curae
=>
'hypnos'
,
penthos
=>
'aporia'
} ),
q{my $obj = Dokimes->new({curae => 'hypnos', penthos => 'aporia'}
)}
);
can_ok(
$obj
,
'limos'
);
eval
{
$obj
->limos( [] ) };
like( $@,
qr/invalid value|greater|atleast/
,
q{$obj->limos([])}
);
eval
{
$obj
->limos( \1 ) };
like( $@,
qr/invalid value|greater|atleast/
,
q{$obj->limos(\1)}
);
eval
{
$obj
->limos(
''
) };
like( $@,
qr/invalid value|greater|atleast/
,
q{$obj->limos('')}
);
eval
{
$obj
->limos(
undef
) };
like( $@,
qr/invalid value|greater|atleast/
,
q{$obj->limos(undef)}
);
ok(
$obj
->penthos(2) &&
$obj
->nosoi(2) &&
$obj
->curae(5),
q{$obj->penthos(2) && $obj->nosoi(2) && $obj->curae(5)}
);
is(
$obj
->limos(
"yay"
), 5,
q{$obj->limos("yay")}
);
ok(
$obj
->penthos(5),
q{$obj->penthos(5)}
);
is(
$obj
->limos(
"yay"
),
''
,
q{$obj->limos("yay")}
);
};
subtest
'clear_nosoi'
=>
sub
{
plan
tests
=> 5;
ok(
my
$obj
= Dokimes->new( {
curae
=>
'hypnos'
,
penthos
=>
'aporia'
} ),
q{my $obj = Dokimes->new({curae => 'hypnos', penthos => 'aporia'}
)}
);
can_ok(
$obj
,
'clear_nosoi'
);
is_deeply(
$obj
->nosoi(10), 10,
q{$obj->nosoi(10)}
);
ok(
$obj
->clear_nosoi,
q{$obj->clear_nosoi}
);
is(
$obj
->nosoi,
undef
,
q{$obj->nosoi}
);
};
done_testing();
and has 100% test coverage.
cover --test
------------------- ------ ------ ------ ------ ------ ------
File stmt bran cond
sub
time
total
------------------- ------ ------ ------ ------ ------ ------
blib/lib/Dokimes.pm 100.0 100.0 100.0 100.0 100.0 100.0
Total 100.0 100.0 100.0 100.0 100.0 100.0
------------------- ------ ------ ------ ------ ------ ------
tests
Unfortunately not all code can have auto generated tests, so you should use the :test attribute to define additional to test custom logic.
ok
This simply evaluates any expression ($got eq $expected is just a simple example) and uses that to determine if the test succeeded or failed. A true expression passes, a false one fails.
[
'ok'
,
'$obj->$method'
]
can_ok
Checks to make sure the $module or $object can do these @methods (works with functions, too).
[
'can_ok'
,
'$obj'
,
$method
]
isa_ok
Checks to see if the given $object->isa($class). Also checks to make sure the object was defined in the first place. Handy for this sort of thing:
[
'isa_ok'
,
'$obj'
,
$class
]
is
Similar to ok(), is() and isnt() compare their two arguments with eq and ne respectively and use the result of that to determine if the test succeeded or failed. So these:
[
'is'
,
'$obj->$method'
,
$expected
]
isnt
[
'isnt'
,
'$obj->$method'
,
$expected
]
like
Similar to ok(), like() matches $got against the regex qr/expected/.
[
'like'
,
'$obj->$method'
,
$expected_regex
]
unlike
Works exactly as like(), only it checks if $got does not match the given pattern.
[
'unlike'
,
'$obj->$method'
,
$expected_regex
]
deep
Similar to is(), except that if $got and $expected are references, it does a deep comparison walking each data structure to see if they are equivalent. If the two structures are different, it will display the place where they start differing.
[
'deep'
,
'$obj->$method'
,
$expected
]
eval
Evaluate code that you expect to die and check the warning using like.
[
'eval'
, '
$obj
->
$method
",
$error_expected
]
AUTHOR
LNATION, <email at lnation.org>
BUGS
Please report any bugs or feature requests to bug-hades at rt.cpan.org
, or through the web interface at https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Hades. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
SUPPORT
You can find documentation for this module with the perldoc command.
perldoc Hades
You can also look for information at:
RT: CPAN's request tracker (report bugs here)
AnnoCPAN: Annotated CPAN documentation
CPAN Ratings
Search CPAN
ACKNOWLEDGEMENTS
LICENSE AND COPYRIGHT
This software is Copyright (c) 2020 by LNATION.
This is free software, licensed under:
The Artistic License 2.0 (GPL Compatible)
1 POD Error
The following errors were encountered while parsing the POD:
- Around line 1339:
Non-ASCII character seen before =encoding in '(£penthos'. Assuming UTF-8