{"id":635,"date":"2022-08-30T15:04:38","date_gmt":"2022-08-30T15:04:38","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2013\/11\/09\/what-is-the-default-parameter-for-autoload-in-perl-collection-of-common-programming-errors\/"},"modified":"2022-08-30T15:04:38","modified_gmt":"2022-08-30T15:04:38","slug":"what-is-the-default-parameter-for-autoload-in-perl-collection-of-common-programming-errors","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2022\/08\/30\/what-is-the-default-parameter-for-autoload-in-perl-collection-of-common-programming-errors\/","title":{"rendered":"What is the default parameter for AUTOLOAD in Perl?-Collection of common programming errors"},"content":{"rendered":"<p>Using Autoload is inherently difficult. If you want a solid object system that makes accessors for you then <strong>please use Moose, Mouse, Moo<\/strong>, or just loop over your fields and install the accessors yourself:<\/p>\n<pre><code>BEGIN {\n  my @fields = qw\/foo bar baz\/;\n  for my $field (@fields) {\n    no strict 'refs';\n    # install a closure in the package stash.\n    *{ __PACKAGE__ . \"::\" . $field } = sub {\n      my $self = shift;\n      $self-&gt;{$field} = shift if @_;\n      return $self-&gt;{$field};\n    };\n  }\n}\n<\/code><\/pre>\n<p>If a class that can <code>AUTOLOAD<\/code> encounters an undefined method, the <code>AUTOLOAD<\/code> sub is called with the arguments of the missing sub. The fully qualified name of the requested sub is passed in the <code>$AUTOLOAD<\/code> package variable.<\/p>\n<p>A typical Autoload sub would look like:<\/p>\n<pre><code>use Carp;\n\nmy %fields_allowed = map {$_ =&gt; 1} qw\/foo bar baz\/;\n\nsub AUTOLOAD {\n  my $field = our $AUTOLOAD;\n  $field =~ s\/.*::\/\/; # strip the package name\n  $fields_allowed{$field}\n    or croak qq(Can't locate object method $field via package \"@{[__PACKAGE__]}\");\n  my $self = shift;\n  $self-&gt;{$field} = shift if @_;\n  return $self-&gt;{$field};\n}\n<\/code><\/pre>\n<p>There remain two problems:<\/p>\n<ul>\n<li>When the reference count of an object drops to zero, or when a thread terminates, the <code>DESTROY<\/code> method is called on the object if it provides one. We can prevent autoloading of <code>DESTROY<\/code> by providing an empty implementation: <code>sub DESTROY {}<\/code>.<\/li>\n<li>We can ask any object if it can perform a certain method, like <code>say \"Good dog\" if $dog-&gt;can(\"roll\")<\/code>. Therefore, we have to override <code>can<\/code> to support our autoloading. The <code>can<\/code> method is useful for safe duck typing. Every object inherits from <code>UNIVERSAL<\/code>, which provides default implementations for <code>can<\/code> and <code>isa<\/code>.<\/li>\n<\/ul>\n<p>The contract of <code>can<\/code> is that it takes the name of a method. It will return <code>undef<\/code> when the object cannot perform the method, or a code reference to that method if it can. A suitable implementation would be<\/p>\n<pre><code>sub can {\n  my ($self, $name) = @_;\n\n  # check if it's a field of ours\n  if ($fields_allowed{$name}) {\n    return sub {\n      my $self = shift;\n      $self-&gt;{$name} = shift if @_;\n      return $self-&gt;{$name};\n    };\n  }\n\n  # Ask SUPER implementation of can if we can do $name\n  if (my $meth = $self-&gt;SUPER::can($name)) {\n    return $meth;\n  }\n  return; # no method found\n}\n<\/code><\/pre>\n<p>We can now simplify <code>AUTOLOAD<\/code> to<\/p>\n<pre><code>sub AUTOLOAD {\n  my $field = our $AUTOLOAD;\n  $field =~ s\/.*::\/\/; # strip the package name\n  my $code = $self-&gt;can($field)\n    or croak qq(Can't locate object method $field via package \"@{[__PACKAGE__]}\");\n  goto &amp;$code; # tail call; invisible via `caller()`.\n}\n<\/code><\/pre>\n<p>This is a lot of complexity to get right. Verdict: Don&#8217;t use Autoload because you think it might be less work. It never is. It is quite useful for implementing a proxy pattern, but that is a bit advanced.<\/p>\n<p>I urge you to dabble around with OO basics, and the Moose object system, before diving deep into Perl&#8217;s unique and strange features.<\/p>\n<p id=\"rop\"><small>Originally posted 2013-11-09 21:09:20. <\/small><\/p>","protected":false},"excerpt":{"rendered":"<p>Using Autoload is inherently difficult. If you want a solid object system that makes accessors for you then please use Moose, Mouse, Moo, or just loop over your fields and install the accessors yourself: BEGIN { my @fields = qw\/foo bar baz\/; for my $field (@fields) { no strict &#8216;refs&#8217;; # install a closure in [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-635","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/635","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=635"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/635\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=635"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=635"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=635"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}