{"id":568,"date":"2015-09-21T20:56:29","date_gmt":"2015-09-22T01:56:29","guid":{"rendered":"http:\/\/www.aibistin.com\/?p=568"},"modified":"2023-03-12T16:14:30","modified_gmt":"2023-03-12T20:14:30","slug":"using-moo","status":"publish","type":"post","link":"https:\/\/www.aibistin.com\/?p=568","title":{"rendered":"Using Moo"},"content":{"rendered":"<p>Moo simplifies OO in Perl.<br \/>\nHere is a Moo class that will provide some information about a file. I will use D.A Golden&#8217;s <a href=\"https:\/\/metacpan.org\/pod\/Path::Tiny\">Path::Tiny<\/a>, because I use this module in almost every script that I write.<\/p>\n<pre class=\"lang:perl decode:true\" title=\"File::Info\">package File::Info;\nuse Moo;\nuse v5.16;\n#-------------------------------------------------------------------------------\n#  Base class to provide information about a given file.\n#-------------------------------------------------------------------------------\nuse Path::Tiny;\nuse File::stat;\nuse Carp;\nuse namespace::clean; #--- Dont export unintentionally\n#-------------------------------------------------------------------------------\n#  Attributes\n#-------------------------------------------------------------------------------\nhas file =&gt; (\n    is  =&gt; 'ro',\n    isa =&gt; sub {\n        Carp::croak(qq{'in_file' needs to be an existing file and a Path::Tiny Object!})\n          unless (ref $_[0] eq 'Path::Tiny' and $_[0]-&gt;exists);\n    },\n    coerce =&gt; sub {\n        return $_[0]\n          if ( ref $_[0] eq 'Path::Tiny' );\n        return path( $_[0] );\n    },\n    required =&gt; 1\n);\n\nhas file_stat =&gt; (\n    is  =&gt; 'rwp',\n    isa =&gt; sub {\n        Carp::croak(qq{$_[0] is not a File::stat::stat!})\n          unless ( $_[0] and ( ref $_[0] ) );\n    },\n);\n\n#-------------------------------------------------------------------------------\n#  Builders and Triggers\n#-------------------------------------------------------------------------------\nsub BUILD {\n    my ($self) = @_;\n    $self-&gt;_set_file_stat( File::stat::stat( $self-&gt;file ) )\n      or Carp::croak( qq{File stat failed to get the file stat for, }\n          . $self-&gt;file\n          . qq{!: $!} );\n}\n1;\n<\/pre>\n<p>It would be a good idea to test this module before we proceed further.<br \/>\nI found a this <a href=\"https:\/\/metacpan.org\/pod\/Test::Modern\">Test::Modern<\/a>\u00a0 module by Toby Inkster(who always does good stuff). It&#8217;s a testing module that includes many other testing modules(Also see <a href=\"https:\/\/metacpan.org\/pod\/Test::Most\">Test::Most<\/a>).<\/p>\n<p>Here&#8217;s\u00a0a test to make sure that all&#8217;s ok with my File::Info module.<\/p>\n<pre class=\"lang:perl decode:true\">use Test::Modern;    #-- I wonder will it be modern in 10 years time??\nuse FindBin qw($Bin);\nuse lib qq{$Bin\/..\/lib};    #-- Where File::Info is located.\nuse File::Info;\n\nmy $fi = object_ok(\n    sub { File::Info-&gt;new( file =&gt; qq{IMAG0029.jpg} ) },\n    '$fi',\n    isa   =&gt; [qw(Moo::Object )],\n    can   =&gt; [qw(  file file_stat )],\n    clean =&gt; 1,\n    more  =&gt; sub {\n        my $file_info_obj = shift;\n\n        isa_ok( $file_info_obj-&gt;file, 'Path::Tiny',\n            q{File::Info 'file' is a Path::Tiny object.} );\n\n        is( $file_info_obj-&gt;file-&gt;basename,\n            qq{IMAG0029.jpg},\n            q{File::Info 'file' has the correct file basename.} );\n\n        isa_ok( $file_info_obj-&gt;file_stat, q{File::stat},\n            qq{File::Info 'file_stat' is a 'File::stat'.} );\n\n        like( $file_info_obj-&gt;file_stat-&gt;size,\n            qr\/^[0-9]+$\/,\n            q{File::Info 'file_stat-&gt;size' returns a numeric file size.} );\n    },\n);\n\ndone_testing();\n<\/pre>\n<p>I ran this test script and got the following results ( on the first attempt of course :)).<\/p>\n<pre class=\"theme:solarized-dark nums:false lang:default decode:true \" title=\"Run 'test_file.t'\">Moo &gt; prove -v t\/test_file.t \nt\/test_file.t .. \n    # Subtest: $fi ok\n    ok 1 - instantiate $fi\n    ok 2 - $fi is blessed\n    ok 3 - '$fi' isa 'Moo::Object'\n    ok 4 - File::Info-&gt;can(...)\n    ok 5 - File::Info contains no imported functions\n        # Subtest: more tests for $fi\n        ok 1 - 'File::Info 'file' is a Path::Tiny object.' isa 'Path::Tiny'\n        ok 2 - File::Info 'file' has the correct file basename.\n        ok 3 - 'File::Info 'file_stat' is a 'File::stat'.' isa 'File::stat'\n        ok 4 - File::Info 'file_stat-&gt;size' returns a numeric file size.\n        ok 5 - no exception thrown by additional tests\n        1..5\n    ok 6 - more tests for $fi\n    1..6\nok 1 - $fi ok\nok 2 - no (unexpected) warnings (via done_testing)\n1..2\nok\nAll tests successful.\nFiles=1, Tests=2,  0 wallclock secs ( 0.03 usr  0.01 sys +  0.09 cusr  0.00 csys =  0.13 CPU)\nResult: PASS\n[21:42 - 0.37]\n[austin@the-general-II 64] Moo &gt;<\/pre>\n<p>Test::Modern seems pretty cool. \u00a0My File::Info module seems to be ok so far. \u00a0Now to add some more useful functionality.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Moo simplifies OO in Perl. Here is a Moo class that will provide some information about a file. I will use D.A Golden&#8217;s Path::Tiny, because I use this module in almost every script that I write. package File::Info; use Moo; use v5.16; #&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;- # Base class to provide information about a given file. #&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;- use [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[107,108,101],"tags":[29,30,20,31],"class_list":["post-568","post","type-post","status-publish","format-standard","hentry","category-moo","category-oop","category-perl","tag-moo","tag-pathtiny","tag-perl","tag-testmodern"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.aibistin.com\/index.php?rest_route=\/wp\/v2\/posts\/568","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.aibistin.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.aibistin.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.aibistin.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.aibistin.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=568"}],"version-history":[{"count":14,"href":"https:\/\/www.aibistin.com\/index.php?rest_route=\/wp\/v2\/posts\/568\/revisions"}],"predecessor-version":[{"id":905,"href":"https:\/\/www.aibistin.com\/index.php?rest_route=\/wp\/v2\/posts\/568\/revisions\/905"}],"wp:attachment":[{"href":"https:\/\/www.aibistin.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=568"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.aibistin.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=568"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.aibistin.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=568"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}