Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Re^3: Correct syntax for using $INC to keep modules in same file

by chromatic (Archbishop)
on Jun 28, 2012 at 02:07 UTC ( [id://978817]=note: print w/replies, xml ) Need Help??


in reply to Re^2: Correct syntax for using $INC to keep modules in same file
in thread can't import using exporter

I don't want to separate each class definition out into a a separate file.

If you were truly using classes, you wouldn't have this problem. You're not using classes. You're reinventing modules, and that badly.

Otherwise it adds unnecessary complexity.
use mem &{sub(){$::INC{'Dbg.pm'}=1}};

That's necessary complexity? Reimplementing something Perl already knows how to do for you—in an ugly and incomplete fashion—is both necessary and sufficiently simple?

Even the syntax use mem 'Dbg'; would be far less blepharitic—no less obnoxious, but at least it would keep the ugliness to only one spot in your code.

Replies are listed 'Best First'.
Re^4: Correct syntax for using $INC to keep modules in same file
by perl-diddler (Chaplain) on Jul 01, 2012 at 04:03 UTC
    But it wouldn't accomplish the same purpose. Besides, I only accept responsibility for the 'use mem' pragma.

    The only purpose of specific line of code is to get around perl's inability to know when module Dbg has already been defined and, therefore, doesn't need to be searched for.

    I'm using classes -- things without separate files, not modules -- which, being modular, do live in separate files. (Are we picking nits about definitions?, you say half-dozen, I say six, or such?)

    So how does one tell Perl, in code that looks like perl code, and not some sort of assembler, that a 'use statement' should not go searching for files, but should use the 'in-memory' version instead? Note: BEGIN{} sticks out like a sore thumb. It doesn't fit with any other pragma.. so it doesn't qualify.

    But I'm sure you love code like this:

    { package Parse_Options; # {{{1 use warnings; use 5.14.0; use mro; our (@ISA,@fields); use mem &{sub(){$::INC{'Parse_Options.pm'}=1}}; use mem &{sub(){our @fields = qw(quiet verbose numprocs ratio_jobs + srcX dstX); our @ISA = (qw(Data::Vars FileList + main)); }}; use Data::Vars \@fields,{quiet=>0,verbose=>0,ratio_jobs=>6/5};
    In order for 'Data::Vars' to work correctly and in order for class inheritance to work at compile time, you have to have your fields (to Data::Vars, and Exporter -- similar problems) declared at 'BEGIN' time -- that's what mem does --- it forces the evaluation of it's args at BEGIN time.

    For example, the use Data::Vars above has initialization args for the default values -- If I misspell or change any -- they are caught at compile time.

    If you want the things you are importing with Exporter to by type-checked at compile time, you have to have them included at BEGIN time by using BEGIN or something like the above.

    I don't remember it always being that way -- it seemed to be something that popped up in 5.12 or 5.14 -- and that was one of the major breakages I saw.

    Another was putting use warnings/use strict; after every package statement --- not just once at the top of the file. I don't remember that being required before 5.14 or maybe 5.12 (my perl pretty much jumped from 5.10->5.14...)....I spent little time with 5.12...

    You think stuff like the above drives you crazy??? I've just given up on perl making sense and decided to code around everything that doesn't make sense -- it was too much work trying to figure out the 'why's ... I could spend all my time doing that or getting something done.

    As it stands, my Wave2Flac converter coverts 600MB Wave->300MB Flac with all optimizations in 8-10 seconds (of course it runs multiple jobs in parallel and uses a queue). Of course it's not really 'done' (want to add both Wav2mp3 & Flac2mp3...)... but that may be a while...dunno.

    Previous working version was ~ 3-4 years ago, and then it took about 30-45 seconds/album.

    My duplicate / outdated rpm code can sort through 13k rpms -- reading each via rpm, in a 2-phase parallel merge/sort -- <2 seconds. I'm not sure why the shell script version took multiple minutes...but it didn't run with 9-10 threads either.

      I don't remember it always being that way...

      You misremember. Perl 5 has worked that way for at least 12 years.

      I don't remember that being required before 5.14 or maybe 5.12...

      You misremember that too.

      I've just given up on perl making sense and decided to code around everything that doesn't make sense -- it was too much work trying to figure out the 'why's....

      The hows and whys have been in the documentation for years. Several people in this thread have tried to explain this to you. You will continue to struggle unless you decide to believe us.

      So how does one tell Perl, in code that looks like perl code, and not some sort of assembler, that a 'use statement' should not go searching for files, but should use the 'in-memory' version instead?

      You do so the same way you tell Perl that sort should load files and grep should shell out to Nethack. In other words, fundamental Perl 5 operations behave as they have been documented and implemented and tested and stable since the earliest versions of Perl 5.

      You are working against Perl and doing things the hard way and your problems reflect that. You have trouble debugging your code because you're doing things the hard way. Why are you continually asking for advice and ignoring that advice?

        You do so the same way you tell Perl that sort should load files and grep should shell out to Nethack.
        So you can't really say. That's why I listen but when told to leap over the cliff, I don't join the lemmings. When I asked that question on the p5p list, I was told "you don't", perl doesn't support using in-memory versions of modules, and we like it that way. It's not a matter of not being able to do it, it's religious zealotry.

        I'm not working against perl, I'm working against the tainted Koolaid. I know it can be better, and I know people are against it being better. My code doesn't work when I try to follow the manpages and manual -- when I go all quirky -- that's when my code works. I hate myself later, but I resolve to keep pushing for change. Usually, the changes I want come about -- but usually happen long after people have forgotten that I tried to push for them years earlier.

        I have trouble debugging my code? The reason I posted here was because perl claims to be UTF-8 compliant, but has a big whole in it's implementation -- in that it treats U+0-U-127 as Unicode, U+128-255 as Latin1, and U+256 and above as UTF-8. That's broken. That has nothing to do with the way I am programming.

        You didn't answer my questions you just continue to speak in riddles referring grep to using nethack while not answering how what I was doing was re-implementing modules and was not implementing same-file Classes that perl lacks?

        You seem to think perl doesn't change, but just looking at the changes from 5.10->5.12-- there was a change in isa -- it went from not working with inheritance to working;

        "object->isa('Foo') would report false if the package Foo didn't exist, even if the object's @ISA contained Foobject->isa('Foo') would report false if the package Foo didn't exist, even if the object's @ISA contained Foo.

        Bugs in autoload related to ISA were fixed, and autoload methods often didn't:"Various bugs in the new-to 5.10.0 mro code, triggered by manipulating @ISA, have been found and fixed.In the 5.10.0 release, a dynamically created AUTOLOAD method might be missed (method cache issue) RT #60220,60232."

        What works in perl in any given release changes. It's documented. You may believe it hasn't changed, but oh well.

        As for the previous anonidjit, knowing when to Export and when to make something a class is a sign of knowing your tools. Always using the same methodology for each problem is... a sure way to obsolescence.

      Inheritance + Exporter = ClownShoes
Re^4: Correct syntax for using $INC to keep modules in same file
by perl-diddler (Chaplain) on Oct 13, 2012 at 22:36 UTC
    Reading through old stuff...(I sometimes do)...

    I do not understand what you are trying to say.

    use mem, which for simple assignments, I've found can be more easily simplified to:

    use mem ($::INC{'Dbg.pm'}=1);
    is a substitute for the UGLY BEGIN block. If there is a more structured way to do it that is prettier, please tell me, but I find BEGIN blocks to be ugly -- I don't like all caps keywords -- they are hard to type and bother my RSI when I do it. So I tend to find lower cost workarounds.

    But the bit you said about "use mem 'Dbg'" -- I don't understand -- are you thinking or saying that such would be a substitute for the previously mentioned code or that I should write a separate module to make it so? If it is the latter, yeah, I could, but its a tradeoff. Any module that doesn't have mem in it's library path can recreated it in 1 line:

    BEGIN{$::INC{mem.pm}=1}
    After that, I can use mem and anything on it's parameter line will be evaluated at BEGIN time without all those ugly BEGIN blocks.

    The most common usage I have for use mem (besides assigning to INC so a module in the same file doesn't have to be loaded), is to assign to ISA and EXPORT at BEGIN time, so various modules, including Exporter will work correctly.

    Exporter won't work fully if you don't do that. It will include the functions you want -- but not their types. I try to always use typed functions. You only get the benefit of that typing if you have your EXPORT list included at BEGIN time.... usemem does that.

    So I'm not sure what you are suggesting I write a module that would have to be included to provide syntactic sugar so it looks nicer? (not necessarily a bad thing, but right now utility beats pretty... pretty comes after it's working -- and I do go back and pretty up code...but usually on a 2nd revision...1st revision is to get it working)...

    Is that wrong, or what are you suggesting?

      Something like this:

      package mem; sub import { my (undef, $package) = @_; $package =~ s!::!/!g; $INC{$package . '.pm'} = 1; }

      As long as that appears logically before any use mem 'foo'; statements in your program, everything should work correctly. It's slightly more typing than your implementation of mem, but it keeps all of the details of the implementation in one place.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://978817]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (3)
As of 2024-04-19 05:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found