0
if (@arr =~ /env1/) #checking enviroment  
{
   # Want to flush the @INC contents using below no lib
   # --> Command before the perl get the libraries of my choice at the time of compilation 

   no lib "//First/lib/"; #flush INC  
   no lib "//Second/lib/"; #flush INC  
   print log1 "INC before current- @INC\n";

   #set library of my choice with either syntax
   BEGIN{ unshift @INC, "//Third/lib/" };                                    
   # or                                      
   use lib "//third/lib/";

   print log1 "INC after- @INC\n";  
   print log2 "INC after- %INC\n";  
   print log3 map {"$_ => $INC{$_}\n"} keys %INC; 

   use DirHandle;  
   use File::Find;  
   use File::Copy;  

   print map {"$_ => $INC{$_}\n"} keys %INC;
}

I want to know the above thing can be achieved in a simpler way. Do I need to include any Perl modules to use the (no lib and use lib commands). This is a requirement due to script running in multiple enviroment and when one of the enviroments is down the script stops running. I want to achieve this by passing the libraries of my choice to be used by perl.

Suggestions are welcome.


Edit: Here's the actual code.

if (@temp[arr_index]=~ /env1/) #enviroment 1
                      {              

                     BEGIN{ unshift @INC, "//server1/lib/" }; #server 1 for same app lower enviroment 1
                     BEGIN{ unshift @INC, "//server2/lib/" }; #server 2 for same app lower enviroment 1

                                    use File::Copy; 

                    }

    elsif (@temp[arr_index]=~ /env2/) #enviroment 2

    {
                    BEGIN{ unshift @INC, "//server1/lib/" }; #server 1 for same app lower enviroment 2
                    BEGIN{ unshift @INC, "//server2/lib/" }; #server 2 for same app lower enviroment 2

                                    use File::Copy;
    }


    elsif (@temp[arr_index]=~ /env3/) #enviroment 3

    {
                    BEGIN{ unshift @INC, "//server1/lib/" }; #server 1 for same app lower enviroment 3
                    BEGIN{ unshift @INC, "//server2/lib/" }; #server 2 for same app lower enviroment 3

                                    use File::Copy;
    }

@INC - Having @INC the values same for all enviroments which is causing issue. Hope the above adds some clarity to your understanding . THANKS.

simbabque
  • 53,749
  • 8
  • 73
  • 136
Sumit N
  • 19
  • 2
  • I doubt `@arr =~ /env1/` does what you want, as this would match the regex against the *length* of `@arr`. To see if any *element* would match the regex, use `grep /env1/, @arr`, or use smart matching: `@arr ~~ qr/env1/` (only available in newer perls). – amon Dec 20 '12 at 12:40
  • Nonsense! You can `use lib`. –  Dec 24 '12 at 04:29
  • 2
    Again, my explanation in my answer stands. Also, this will not work. This code should not compile. What is `arr_index`? I suggest you start your program with a the Perl debugger (run it on the command line with `perl -d`) and step through it. You will see in what order it calls the `BEGIN` blocks. If you don't believe me, you will be surprised. Also, Merry Chrismas! – simbabque Dec 24 '12 at 10:51
  • @Sim- I am new to perl apologies for any silly mistakes if you see. I think the best way to learn is doing mistakes and correcting them. – Sumit N Dec 25 '12 at 02:18
  • arr_index will have the index number of array where . I will be getting the enviroment name captured.It is like @temp[3] =~ /env1/. I am understanding what you are trying to explain that the BEGIN blocks will be executed regardless of the if else block specified in my code which are the run time commands... I guess the problem lies here only @INC is getting initialized by the first BEGIN only for using lib files and at the run time the if else conditions are checked which is of no use and giving no logic to the code . Please add inputs and suggestions.. – Sumit N Dec 25 '12 at 02:19

1 Answers1

0

I would suggest just pushing all of them into @INC in the order of your preferred environments. Perl will look at the contents of @INC. Perlvar says about it:

The array @INC contains the list of places that the do EXPR , require, or use constructs look for their library files.

That means it will look at the list of paths from left to right, as described here. Thus, you can just push your library paths into @INC one after another:

@!/usr/bin/perl
use strict;
use warnings;

BEGIN {
  use lib 'first/lib', 'second/lib', 'third/lib';
}

If you now go and require Some::Module, Perl will look in first/lib first. If it cannot find it there, maybe because the path doesn't exist in your environment (it won't complain about that), Perl will proceed to look in second/lib and third/lib one after the other. You don't have to do anything else.

-- On another note, you have mixed compile time and run time a lot in your above code. The three use parts and the BEGIN block will be called at compile time regardless of the if construct they are in. Everything else, including the no lib calls will only be called at run time if the match is true. See perlmod for a more detailed explanation of how this works.

Community
  • 1
  • 1
simbabque
  • 53,749
  • 8
  • 73
  • 136
  • On confusing run-time with compile-time: Didn't you just `BEGIN{use ...}` something? That *looks* superfluous to me. – amon Dec 20 '12 at 12:45
  • Thanks for the feed back ... I will get back to you once i work on the code as per your suggestions. – Sumit N Dec 21 '12 at 05:08
  • SIM- your suggestion for pusshing all the library of my choice in @INC and allow perl to use it left to right .... this is already in place and the requirement is to get rid of this because of some enviroment constraint under which perl is running because the libraries inside INC are actually different servers where they are located and it gets stop if it doesnt find that library on a particular server due to unavability/no access of server . If you can provide something which is focused more on the above that will be very helpful... – Sumit N Dec 21 '12 at 11:25
  • Any suggestions on my above description ... it will be great help ... :-) – Sumit N Dec 23 '12 at 06:09
  • @SumitN you will need to show the actual code and describe the environment in more detail. What kind of different servers? Is a copy of your app running on several different servers? Have you thought about putting the dependencies into a configuration file? You can have one for each server. – simbabque Dec 23 '12 at 11:56
  • @SIM- You are right , the servers are windows server 2003 , Yes the servers are the application servers (and each is responsible to have my application installed and running having seperate lib files installed on the server for the use of Perl script to execute). I havent thought of putting the dependencies in the configurations file. As described earlier this is the scenario where I want that dependencies to be removed because it causes stopage to perl script execution if my LIB files are referred to the server which is unavailable. The actual code goes like below. – Sumit N Dec 24 '12 at 04:22