{"id":2333,"date":"2019-09-18T11:51:19","date_gmt":"2019-09-18T15:51:19","guid":{"rendered":"https:\/\/blog.jonesling.us\/?p=2333"},"modified":"2019-12-13T21:57:46","modified_gmt":"2019-12-14T02:57:46","slug":"perl-spaces-in-a-function-or-method-name","status":"publish","type":"post","link":"https:\/\/blog.jonesling.us\/?p=2333","title":{"rendered":"Perl: Spaces in a function or method name"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">I accidentally stumbled over an interesting ability\/quirk in Perl: a subroutine \/ function \/ method name may contain spaces.  Since I couldn&#8217;t find any info about it in the perlsub man page or on Google I decided to write it down.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It should be obvious that you can&#8217;t create such a subroutine by defining it the traditional way, but in case it isn&#8217;t: you can&#8217;t.  Perl will consider the first word to be your subroutine identifier, and the following word(s) to be invalid keywords.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: perl; gutter: false; title: ; notranslate\" title=\"\">\nuse strict;\n\nsub name With Spaces\n{\n    print &quot;works!\\n&quot;; # liar, doesn&#039;t work\n}\n<\/pre><\/div>\n\n\n<pre class=\"wp-block-preformatted\">Illegal declaration of subroutine main::name line 4.<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">NOTE: the following examples were tested in Perl versions 5.8.8 (circa 2006), 5.14.2 (circa 2011), and 5.28.2 (circa 2019).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To create a method name with a space, you have to manipulate the symbol table directly.  (Indeed, I figured it out by accident thanks to an <code>AUTOLOAD<\/code>ed method that did that.)<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: perl; title: ; notranslate\" title=\"\">\nsub AUTOLOAD\n{\n    my $self = shift;\n\n    ( my $method = $AUTOLOAD ) =~ s{.*::}{};\n\n    if ( exists $self-&gt;{_attr}-&gt;{ $method } ) {\n        my $accessor = sub { return shift-&gt;{_attr}-&gt;{ $method } };\n\n        {\n            no strict &#039;refs&#039;;\n            *$AUTOLOAD = $accessor;\n        }\n\n        unshift @_ =&gt; $self;\n        goto &amp;$AUTOLOAD;\n    }\n\n    return;\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Stated more simply:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: perl; gutter: false; title: ; notranslate\" title=\"\">\nmy $name = &quot;name With Space&quot;;\n*$name = sub { &quot;works!&quot; }; # insert directly to symbol table\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Utilities like <code>Test::Deep<\/code> &#8220;just work&#8221; if there&#8217;s a space:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: perl; gutter: false; title: ; notranslate\" title=\"\">\ncmp_methods( $obj,\n             &#x5B; &#039;name With Space&#039; =&gt; &#039;value&#039; ], # not a peep!\n             &#039;Basic methods&#039;\n            );\n<\/pre><\/div>\n\n\n<pre class=\"wp-block-preformatted\">ok 1 - Basic Methods<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The obvious question, though, is how to access it directly?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can access a method using a variable, which is a pretty common thing to do on it&#8217;s own.  (In my experience, anyway, YMMV).<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: perl; gutter: false; title: ; notranslate\" title=\"\">\nmy $name = &#039;name With Space&#039;;\nmy $value = $obj-&gt;$name; # works!\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">You can also create a reference to a string and immediately deference it.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: perl; gutter: false; title: ; notranslate\" title=\"\">\nmy $value = $obj-&gt;${ \\&#039;name With Space&#039; }; # works!\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">The second example works with regular function calls as well.  Here&#8217;s a stand-alone example:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: perl; gutter: false; title: ; notranslate\" title=\"\">\nuse strict;\n\n{\n    no strict &quot;refs&quot;;\n    my $name = &quot;name With Space&quot;;\n    *$name = sub { &quot;works!&quot; };\n}\n\nprint ${ \\&quot;name With Space&quot; }, &quot;\\n&quot;;&#039; # prints &quot;works!&quot;\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">I can&#8217;t recommend creating subroutines with spaces in the name as good style, but it&#8217;s helpful to know that it can happen and how to work with it when it does.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I accidentally stumbled over an interesting ability\/quirk in Perl: a subroutine \/ function \/ method name may contain spaces. Since I couldn&#8217;t find any info about it in the perlsub man page or on Google I decided to write it down. It should be obvious that you can&#8217;t create such a subroutine by defining it &hellip; <a href=\"https:\/\/blog.jonesling.us\/?p=2333\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Perl: Spaces in a function or method name&#8221;<\/span><\/a><\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_crdt_document":"","wprm-recipe-roundup-name":"","wprm-recipe-roundup-description":"","advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[32],"tags":[389,28],"class_list":["post-2333","post","type-post","status-publish","format-standard","hentry","category-programming-2","tag-perl","tag-programming"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p4o3FW-BD","jetpack-related-posts":[],"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/blog.jonesling.us\/index.php?rest_route=\/wp\/v2\/posts\/2333","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.jonesling.us\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.jonesling.us\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jonesling.us\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jonesling.us\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2333"}],"version-history":[{"count":21,"href":"https:\/\/blog.jonesling.us\/index.php?rest_route=\/wp\/v2\/posts\/2333\/revisions"}],"predecessor-version":[{"id":2406,"href":"https:\/\/blog.jonesling.us\/index.php?rest_route=\/wp\/v2\/posts\/2333\/revisions\/2406"}],"wp:attachment":[{"href":"https:\/\/blog.jonesling.us\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2333"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jonesling.us\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2333"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jonesling.us\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2333"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}