{"id":19640353,"url":"https://github.com/kentnl/path-scaninc","last_synced_at":"2025-10-14T18:35:41.023Z","repository":{"id":2808314,"uuid":"3809371","full_name":"kentnl/Path-ScanINC","owner":"kentnl","description":"Emulate Perls internal handling of @INC","archived":false,"fork":false,"pushed_at":"2017-03-02T03:57:45.000Z","size":305,"stargazers_count":1,"open_issues_count":4,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-14T18:35:38.211Z","etag":null,"topics":["perl"],"latest_commit_sha":null,"homepage":"","language":"Perl","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kentnl.png","metadata":{"files":{"readme":"README.mkdn","changelog":"Changes","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-03-23T14:54:27.000Z","updated_at":"2017-03-02T03:49:09.000Z","dependencies_parsed_at":"2022-09-10T15:11:13.527Z","dependency_job_id":null,"html_url":"https://github.com/kentnl/Path-ScanINC","commit_stats":null,"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"purl":"pkg:github/kentnl/Path-ScanINC","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kentnl%2FPath-ScanINC","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kentnl%2FPath-ScanINC/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kentnl%2FPath-ScanINC/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kentnl%2FPath-ScanINC/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kentnl","download_url":"https://codeload.github.com/kentnl/Path-ScanINC/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kentnl%2FPath-ScanINC/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279020352,"owners_count":26086866,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-14T02:00:06.444Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["perl"],"created_at":"2024-11-11T14:05:33.219Z","updated_at":"2025-10-14T18:35:41.007Z","avatar_url":"https://github.com/kentnl.png","language":"Perl","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NAME\n\nPath::ScanINC - Emulate Perls internal handling of @INC.\n\n# VERSION\n\nversion 1.000004\n\n# SYNOPSIS\n\nThe Aim of this module is to fully implement everything Perl does with `@INC`, to be feature compatible with it, including\nthe behavior with regard to `sub refs` in `@INC`.\n\n        use Path::ScanINC;\n\n        # Normal usage.\n        my $inc = Path::ScanINC-\u003enew( );\n\n        # In case you need something that isn't @INC\n        # but works like it\n\n        my $inc = Path::ScanINC-\u003enew( inc =\u003e \\@INC );\n\n        # Freeze the value of @INC at the time of object instantiation\n        # with regard to behaviour so later changes to @INC have no effect\n\n        my $inc = Path::ScanINC-\u003enew( immutable =\u003e 1 );\n\n        # Return the first file in @INC that matches.\n\n        my $file = $inc-\u003efirst_file('Path', 'ScanINC.pm' );\n\n        # Find all possible versions of modules in @INC\n        my ( @files ) = $inc-\u003eall_files('Path', 'ScanINC.pm');\n\n        # Try to discover a File::ShareDir 'module' root.\n        my $dir = $inc-\u003efirst_dir('auto','share','module');\n\n        # Should return the same as File::ShareDir::module_dir('Path::ScanINC')\n        # ( assuming such a directory existed, which there is presently no plans of )\n        my $dir = $inc-\u003efirst_dir('auto','share','module','Path-ScanINC');\n\n\n        # Find All File::ShareDir roots in @INC\n        my ( @dirs ) = $inc-\u003eall_dirs('auto', 'share');\n\n# DESCRIPTION\n\n`Path::ScanINC` is a basic tool for traversing `@INC` in a `perl`-like manner, stepping over some common\npitfalls with using it. It also has the property of being able to capture `@INC` states to emulate a portable\nisolated library resolver.\n\n# REF SUPPORT IN @INC\n\nThis module has elemental support for discovery of results in `@INC` using `CODE`/`ARRAY`/`BLESSED` entries in\n`@INC`. However, due to a limitation as to how `perl` itself implements this functionality, the best we can do at present\nis simply return what the above are expected to return. This means if you have any of the above ref-types in `@INC`,\nand one of those returns `a true value`, you'll get handed back an `ARRAY` reference instead of the file you were\nexpecting.\n\nFortunately, `@INC` barely ever has refs in it. But in the event you _need_ to work with refs in `@INC` and you\nexpect that those refs will return `true`, you have to pick one of two options, either :\n\n- a. Write your code to work with the `array-ref` returned by the respective reference on a match\n- b. Use the `all_` family of methods and try pretending that there are no `array-refs` in the list it returns.\n\nIts possible in a future release we may have better choices how to handle this situation in future, but don't bet on it.\n\nGiven that the API as defined by Perl mandates `code-ref`'s return lists containing `file-handles` or iterative\n`code-ref`'s , not actual files, the best I can foresee at this time we'd be able to do to make life easier for you is\ncreating a fake library somewhere in a `tempdir` and stuffing the result of the `code-ref`'s into files in that directory\nprior to returning a path to the generated file.\n\n( And it also tells me that they have to be \"Real\" file handles, not tied or blessed ones, so being able to ask a\n`filehandle` what file it represents is equally slim.... if that is of course what you require )\n\nFor more details, see [`perldoc perlfunc` or `perldoc -f require` ](https://metacpan.org/pod/perlfunc#require).\n\n# METHODS\n\n## new\n\n        my $object = $class-\u003enew(\n                 inc =\u003e [ 'x', 'y', 'z' , ],\n                 immutable =\u003e 1 | undef\n        );\n\n## immutable\n\n        if( $inc-\u003eimmutable ) {\n                print \"We're working with a snapshotted version of @INC\";\n        }\n\n## inc\n\n        for my $i ( $inc-\u003einc ) {\n                say \"Plain: $incer\" if not ref $incer;\n                say \"Callback: $incer\" if ref $incer;\n        }\n\nReturns a copy of the internal version of `@INC` it will be using.\n\nIf the object is `immutable`, then this method will continue to report the same value as c\u003c@INC\u003e, or will be updated\nevery time the original array reference passed during construction gets updated:\n\n        my $ref = [];\n        my $a = Path::ScanINC-\u003enew( inc =\u003e $ref );\n        my $b = Path::ScanINC-\u003enew( inc =\u003e $ref, immutable =\u003e 1 );\n\n        push @{$ref} , 'a';\n\n        is( [ $a-\u003einc ]-\u003e[0] , 'a' , \"non-immutable references keep tracking their original\" );\n        isnt( [ $b-\u003einc ]-\u003e[0] , 'a' , \"immutable references are shallow-copied at construction\" );\n\nDo note of course that is a **SHALLOW** copy, so if you have multiple `@INC` copies sharing the same `array`/`bless`\nreferences, changes to those references will be shared amongst all `@INC`'s .\n\n## first\\_file\n\n        if( defined ( my $file = $inc-\u003efirst_file('Moose.pm') ) {\n                print \"Yep, Moose seems to be available in \\@INC , its at $file, but its not loaded (yet)\\n\";\n        }\n\nThis proves to be a handy little gem that replaces the oft used\n\n        if( try { require Moose ; 1 } ){\n                Yadayadayada\n        }\n\nAnd adds the benefit of not needing to actually source the file to see if it exists or not.\n\n#### **IMPORTANT**: PORTABILITIY\n\nFor best system portability, where possible, its suggested you specify paths as arrays\nof strings, not slash-separated strings.\n\n        $inc-\u003efirst_file('MooseX' , 'Declare.pm')  # Good\n        $inc-\u003efirst_file('MooseX/Declare.pm')      # Bad.\n\nThis is for several reasons, all of which can be summarized as \"Windows\".\n\n- `%INC` keys all use Unix notation.\n- `@INC` callbacks expect Unix notation.\n- `\\` is a valid path part on Unix.\n- On Win32, we have to use `\\` Separation, not `/` for resolving physical files.\n\nThe sum of these means if you do this:\n\n        $inc-\u003efirst_file('MooseX/Declare.pm')\n\nOn win32, it might just end up doing:\n\n        C:\\some\\path\\here/MooseX/Declare.pm\n\nWhich may or may not work.\n\nAnd additionally, if the above module is loaded, it will be loaded as\n\n        \"MooseX/Declare.pm\"\n\nin `%INC`, not what you'd expect, `MooseX\\Declare.pm`\n\n## all\\_files\n\nReturns all matches in all `@INC` paths.\n\n        my $inc = Path::ScanINC-\u003enew();\n        push @INC, 'lib';\n        my ( @files ) = $inc-\u003eall_files('Something','Im','Working','On.pm');\n        pp(\\@files );\n\n        # [\n        #    '/something/........./lib/Something/Im/Working/On.pm',\n        #    '/something/....../share/per5/lib/site_perl/5.15.9/Something/Im/Working/On.pm',\n        # ]\n\nChances are if you understand how this can be useful, you'll do so immediately.\n\nUseful for debugging what module is being loaded, and possibly introspecting information about\nmultiple parallel installs of modules in `%ENV`, such as frequently the case with 'dual-life' modules.\n\n        perl -MPath::ScanINC -E 'my $scanner = Path::ScanINC-\u003enew(); say for $scanner-\u003eall_files(qw( Scalar Util.pm ))'\n        /usr/lib64/perl5/vendor_perl/5.12.4/x86_64-linux/Scalar/Util.pm\n        /usr/lib64/perl5/5.12.4/x86_64-linux/Scalar/Util.pm\n\nSort-of like ye' olde' `perldoc -l`, but more like `man -a`\n\nI might even be tempted to make a sub-module to make one-liners easier like\n\n        perl -MPath::ScanINC::All=Scalar/Util.pm\n\n**REMINDER**: If there are `REFS` in `@INC` that match, they'll return `array-ref`'s, not strings.\n\n## first\\_dir\n\nJust like `first_file` except for locating directories.\n\n## all\\_dirs\n\nJust like `all_dirs` except for locating directories.\n\n# AUTHOR\n\nKent Fredric \u003ckentnl@cpan.org\u003e\n\n# COPYRIGHT AND LICENSE\n\nThis software is copyright (c) 2017 by Kent Fredric \u003ckentnl@cpan.org\u003e.\n\nThis is free software; you can redistribute it and/or modify it under\nthe same terms as the Perl 5 programming language system itself.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkentnl%2Fpath-scaninc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkentnl%2Fpath-scaninc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkentnl%2Fpath-scaninc/lists"}