Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Re: __DATA__ used in BEGIN

by moritz (Cardinal)
on Nov 06, 2007 at 11:27 UTC ( [id://649187]=note: print w/replies, xml ) Need Help??


in reply to __DATA__ used in BEGIN

You can't use <DATA> in a BEGIN block because that BEGIN block is executed at compile time, i.e. before the rest of the file is even parsed.

If you don't need BEGIN time, you could try to stuff your routine that works with the data into a CHECK or INIT block.

But it's hard to give an advise without knowing why you need which data at compile time.

Replies are listed 'Best First'.
Re^2: __DATA__ used in BEGIN
by Tabari (Monk) on Nov 06, 2007 at 13:40 UTC
    Some further context seems indeed to be appropriate.
    In our version control system, we have rules to associate the names of some objects with a specific location in a directory structure.
    We made a perl wrapping around our VC system to automate this logic and to avoid the creation of too many categories. At that time, we were already faced with a history of objects which did not fit the pattern.
    For these objects , hashes were created, as a kind of exception to the rule and these were initialized at the loading the module.
    Alas, as so often happens, exceptions proliferated, so this list became rather long, which lead to my question above.
    To be short, a (huge) hash has to be initialised at run time.
    Tabari

      Why can you not just:

      my %hugeHash = eval do {local $/; <DATA>}; ... __DATA__ exception1 => 'wibble', ...

      to load your hash from the data section? You could make it a whole lot more robust, but if you want quick and dirty that gets you going.


      Perl is environmentally friendly - it saves trees
      For these objects , hashes were created, as a kind of exception to the rule and these were initialized at the loading the module.

      ...

      To be short, a (huge) hash has to be initialised at run time.

      This is still confusing. Are you sure you need to do this in a BEGIN block? If you really need to initialize this hash "at runtime" as you say, then you can do it in normal code. (And if you can do it in normal code, I would suggest calling a sub that returns the hash, rather than using __DATA__.)

      Also unclear is whether this initialization is happening in a script or in a module. If it's a module and you just need the hash to be created when the module is used, then again a BEGIN block is not necessary. If, on the other hand, it's in a script and you need the hash to be created before any modules are loaded, then BEGIN is necessary.

      It would help to see some actual code here.

        Part of the messy structure is of course due to the fact that it is a cleanup.
        The initialisation of the hash was done in the BEGIN section, I wanted to preserve the original structure, but apart from that, there is no real need and it can indeed be replaced by a subroutine call.
        Difficult to say where such a cleaning effort should stop and hints on that would be most welcome too.
        This is part of my BEGIN section, I left out part of the here document, as it is not instructive, but it is of course the source of the big hash:
        # # Intiliase global data and hint settings # BEGIN { %database_platforms = ( "ora" => "Oracle", "sql" => "Sybase", "mss" => "Mssql" ); my %hints_setting = ( "MODULE" => \&set_object_module_hint, "TYPE" => \&set_object_type_hint, "TEMPLATE" => \&set_object_template_hint ); my $hints = <<HINTS_DATA; TYPE:unknown:f_ali_alb_init_profile.mss:procedure TYPE:unknown:f_ali_alb_init_profile.ora:procedure MODULE:unknown:v_state_dr.ora:misc HINTS_DATA my @hints = split /\n/, $hints; foreach (@hints) { chomp; my @line = split /:/; my $proc = $hints_setting{ shift @line }; &{$proc}( @line ) if ($proc); } $history_delimitertext = "--DO NOT CHANGE BELOW THIS LINE--LASTLOG +="; }
        The (already exisitng) module set_object_module_hint goes as follows:
        sub set_object_module_hint { my ($project) = $_[0]; my ($objectname) = $_[1]; my ($modulename) = lc ($_[2]); $modulename =~s/\s//g; my ($result); $result = 0; if ($modulename eq "misc") { if (exists $object_module_hints {$objectname}) { log_message "Overriding module hint '$modulename' for data +base object name '$objectname'"; } $object_module_hints {$objectname} = $modulename; $result = 1; } else { log_error "Invalid module hint '$modulename' for database object + name '$objectname'"; } return $result; }
        The global variable is used in some places, but not too many, so I am inclined to follow your suggestion.

        Tabari

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (5)
As of 2024-03-28 15:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found