Skip to content

Instantly share code, notes, and snippets.

@trwyant
Created December 29, 2021 16:28
Show Gist options
  • Select an option

  • Save trwyant/2070ccbd7765f3d0b54ab1f5786199bf to your computer and use it in GitHub Desktop.

Select an option

Save trwyant/2070ccbd7765f3d0b54ab1f5786199bf to your computer and use it in GitHub Desktop.

Revisions

  1. trwyant created this gist Dec 29, 2021.
    62 changes: 62 additions & 0 deletions lexical-pragmas
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,62 @@
    #!/usr/bin/env perl

    use 5.010;

    use strict;
    use warnings;

    package Noise;

    BEGIN {
    # This trick prevents 'use Noise ...' from trying to find and load
    # Noise.pm.
    $INC{'Noise.pm'} = $0;
    }

    # The convention for naming %^H keys is "name-space/key-name".
    use constant NOISE => join '/', __PACKAGE__, 'noise';

    # This gets called implicitly by 'use Noise ...'
    sub import {
    $^H{ +NOISE } = $_[1]; # $_[0] is the package name.
    return;
    }

    sub noise {
    my $hints_hash = ( caller 0 )[10];
    return $hints_hash->{ +NOISE };
    }

    sub call_import {
    my ( $invocant, @args ) = @_;
    return $invocant->import( @args );
    }

    package main;

    use Noise 'The dog barks';
    say Noise->noise(); # The dog barks

    {
    use Noise 'The cat meows';
    say Noise->noise(); # The cat meows
    }

    # The previous value is restored on scope exit
    say Noise->noise(); # The dog barks

    BEGIN {
    Noise->import( 'The cow moos' );
    }
    # A BEGIN block is good enough. No magic specific to 'use'
    say Noise->noise(); # The cow moos

    BEGIN {
    {
    Noise->call_import( 'The giraffe says nothing' );
    }
    }
    # Scopes, or even call frames, in a BEGIN do not matter when setting %^H
    say Noise->noise(); # The giraffe says nothing

    # ex: set textwidth=72 :