BrowserUk has asked for the wisdom of the Perl Monks concerning the following question:

How can I detect if a glob exists?

Also, has anyone ever written a program (in any language, but particularly Perl) that used more than 4000 classes, or a million instances* of a given class?

Update: * That should have read "concurrent instances".


Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"Think for yourself!" - Abigail
"Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon

Replies are listed 'Best First'.
Re: exists *{$glob} ? (+)
by Zaxo (Archbishop) on Sep 09, 2004 at 07:02 UTC

    Foo{THING} notation is convenient for this,

    my $glob = 'FOO'; if (defined do { no strict 'vars'; *$glob{IO}}) { # ... }
    or if you can hardcode the name of the glob,
    if (defined *FOO{IO}) { # ... }
    The foo{THING} is actually an IO::Handle object, a reference, so you can get by with
    if (*FOO{IO}) { # ... }

    After Compline,
    Zaxo

Re: exists *{$glob} ? (+)
by davido (Cardinal) on Sep 09, 2004 at 07:09 UTC

    Is this what you mean?

    *TGlob; # Create a typeglob named 'TGlob'. print "It's there!\n" if exists $::{'TGlob'}; __OUTPUT__ It's there!

    Update: Just to clarify.... Typeglobs are the containers for Perl's package global variables. Really they're symbol entries in a particular package's symbol table hash. Package main's symbol table is accessed via %::, or %main::. I'm just checking the global symbol table to see if an entry exists for a particular symbol. If it exists, you've got a typeglob.


    Dave

      Further that to that you should also check for glob-ness since non-globs can live in symbol tables e.g
      use strict; sub exists_glob { my $tbl = \%main::; $tbl = $tbl->{"$_\::"} for split '::', scalar caller; return exists $tbl->{$_[0]} && 'GLOB' eq ref \$tbl->{$_}; } $main::{foo} = "I'm a string"; *bar = \"I'm in a glob"; printf "%s is%s a glob\n", $_, (exists_glob($_) ? '' : "n't") for qw/ foo bar /; __output__ foo isn't a glob bar is a glob
      HTH

      _________
      broquaint

        Replacing the $main::{foo} line with sub foo (I am a string); gives a more realistic example.
Re: exists *{$glob} ? (+)
by BUU (Prior) on Sep 09, 2004 at 07:02 UTC
    A) $foo; print "yes" if exists %main::->{foo};
    B) I don't think I have, but I can easily imagine a long running server doing so, for every connection it would create a new IO::Socket object, 1000 connections a day, 100 days, etc.
Re: exists *{$glob} ? (+)
by ikegami (Patriarch) on Sep 09, 2004 at 07:50 UTC
    Also, has anyone ever written a program (in any language, but particularly Perl) that used more than 4000 classes, or a million instances* of a given class?

    yes, just now, just so I could say I did.

    >perl -le "push(@a, bless({}, sprintf('MyClass%04d',$i++))) foreach (1..4001); print(scalar(@a));" 4001 >perl -le "push(@a, bless({}, 'MyClass')) foreach (1..1000001); print(scalar(@a));" 1000001

    Check the two snippets called "Symtab Exploration" in ikegami's scratchpad for code looking at the symbol table. Combine that code with *name{TYPE} to look for things other than package names.

      I guess I could requalify the question with something like "Has anyone ever written a useful, practical, program that used more than 4000 concurrent classes, or 1 million concurrent instances of any given class", but then you could say that your snippets were useful because they proved it could be done :)

      An idea I am playing with uses a 32-bit value as a handle to object instances. That dword will indicate both the class, and the instance of that class. There are various ways that I could subdivide the bits. 64K instances x 64k classes. 16M x 256 etc. Looking at the possible splits, I've pretty much concluded that 12-bits for classes and 20-bits for instances is a reasonable split for most purposes, but was trying to elicit a responcse of "Yeah! My Finite Element Analysis (or Ray Tracing) program routinely has over a million concurrent instances of xxx class" or similar.

      In theory, and probably practice, it would be possible to define the split at compile time. Given most current processors are 32-bit/4GB max memory, and each instance of a class is always going to be more than 1 byte, it is unlikely that any single program will create more that 2**32 concurrent instances of all classes. If, as, and when the program was ever moved to a 64-bit platform, 4GB instances of 4GB classes will suffice for most purposes.

      So, it is just a case of trying to decide what would be the most suitable default split for the 32-bits?


      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "Think for yourself!" - Abigail
      "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
Re: exists *{$glob} ? (+)
by dragonchild (Archbishop) on Sep 09, 2004 at 12:00 UTC
    Yes, I have written code that used more than 4000 classes. I had an application (that's still in use) that needed to support three versions of a communication protocol. Each version had between 3k and 5k messages, with some 1k different components that could be used by a given message. I made every component and every message a different class and maintained them with a bunch of scripts. This was in addition to the 20k lines that I actually maintained by hand.

    I've never had the RAM to support 1M concurrent instances of anything (save for ints).

    ------
    We are the carpenters and bricklayers of the Information Age.

    Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

    I shouldn't have to say this, but any code, unless otherwise stated, is untested

      That leaves a couple of questions:

      1. If you were writing the program over, would you use the same strategy of thousands of classes, or might you switch to a more conventional scheme?
      2. Can you imagine writing a program that would use more than 8000 classes and need more than 500k instances of any single class active concurrently?

      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "Think for yourself!" - Abigail
      "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
        1. As I didn't have a database I could use, then I would definitely use that scheme. Ideally, I would've stored everything in a database.
        2. 8k classes? Yes, in the kind of situation I described earlier. 500k instances? Uhhh ... assuming you used 1k of RAM per instance, which is a lowball estimate, you would need 500M of RAM, just for those objects. If you're doing something that resource-intensive, you probably need it to actually complete running before the Sun dies. So, you're probably not writing it in Perl. Either that or you should've use a database.

        ------
        We are the carpenters and bricklayers of the Information Age.

        Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

        I shouldn't have to say this, but any code, unless otherwise stated, is untested