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

Hi monks, I am trying to create a perl library and link it to my code.Here is the method I followed.
####Code of Library#### package Foo1; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK $debug %EXPORT_TAGS); require Exporter; @ISA = qw(Exporter); @EXPORT = qw('bar'); sub bar { print "Hello \n"; } 1; ################################ ################################ ######parent Code ****########## #######test.pl################# use Foo1; Foo1->bar(); ##################################
Steps followed: 1.going to the directory(Documents>>New Folder)which is where my script of Foo1.pm is there. 2. Type h2xs -XA -n Foo1 3. A folder called Foo1 is created. Enter the folder. 4. the directory now is Documents>> New Folder>>Foo1. 5. type perl makefile.pl 6. Type dmake 7. Type dmake install 8. Copy the whole Foo1 folder and Foo1.pm at C:/ Strawberry/Perl/ Lib and C:/ Strawberry/Perl/ Site/Lib. 9. compile the parent code by getting out of foo1 and into documents>> new folder and typing perl test.pl. (Because my test.pl is saved at this directory). but i get following error.: Can't locate object method "bar" via package "Foo1" at test.pl Please help ....where is the prob?????

Replies are listed 'Best First'.
Re: making a library
by NetWallah (Canon) on Mar 08, 2011 at 06:54 UTC
    You have not created an OBJECT.

    "Foo1" is a module/package/class (depending on how you want to look at it), but it is NOT an object (at least in the OO perl sense).

    If you want to call bar without creating and object, call the class method:

    Foo1::bar();
    If you want to create an object, since you do not have a "new" method, you can try (untested):
    my $obj = bless {},"Foo1"; $obj->bar(); # Calling an instance method. # this passes DIFFERENT parameters than the class method, + above.

         Syntactic sugar causes cancer of the semicolon.        --Alan Perlis

      Hi, I tried using your method :
      Foo1::bar();
      but it shows error "undefined subroutine &Foo1::bar()called"
        Looks like you did not "use Foo1;" before attempting to call the class method.

        Here is pared-down working code: First, the Foo1.pm file

        package Foo1; use strict; sub bar { print "Hello (FIRST Param=$_[0]) (Second-param=$_[1])\n"; } 1;
        Now the code to call Foo1:
        use strict; use warnings; use Foo1; my $obj = bless {},"Foo1"; $obj->bar( "Instance Method"); # Calling an instance method. # this passes DIFFERENT parameters than the class method. Foo1::bar("Class Method call"); Foo1->bar("Pseudo-method call");
        Results:
        Hello (FIRST Param=Foo1=HASH(0xa165818)) (Second-param=Instance Method +) Hello (FIRST Param=Class Method call) (Second-param=) Hello (FIRST Param=Foo1) (Second-param=Pseudo-method call)

             Syntactic sugar causes cancer of the semicolon.        --Alan Perlis

Re: making a library
by GrandFather (Saint) on Mar 08, 2011 at 07:24 UTC

    Actually if you are taking small steps toward an OO module then you have too much stuff in your module. You can trim it to just:

    use strict; use warnings; package Foo; sub bar { print "Hello \n"; } 1;

    With the driver script you showed and Foo.pm in the same directory that will print "Hello" as expected. That's it. Nothing more is required. If you copy Foo.pm to your Perl's site/lib folder it will still work and now you can use Foo.pm from anywhere.

    Unless you are preparing a module for CPAN, there need be nothing more to making your library available than that.

    True laziness is hard work
      Hi, Tried following your suggestion but the same problem persists. Foo2->bar(); ###Cant locate object method "bar" via package Foo2.

        With Foo.pm in the same directory as test.pl (assuming that is the current directory when you run test.pl) where test.pl contains:

        use strict; use warnings; use Foo; Foo->bar(); Foo::bar();

        I get:

        Hello Hello

        Using either the name space variant (Foo::bar) or the class method variant (Foo->bar) of calling bar makes no difference for this code because the "Foo" parameter passed into the class method call variant is not used.

        The important thing is that the path to Foo.pm is in @INC. To check that you could alter test.pl to:

        use Foo; print join "\n", @INC, ''; Foo->bar(); Foo::bar();

        and check that the list of paths includes the path to Foo.pm. You also need to ensure that the file name case and package case match: use Foo everywhere - not foo, FOO or some other variant, but Foo everywhere.

        True laziness is hard work
        have you changed "use Foo1" to "use Foo2" in the script that calls the subroutine? Have you changed the name of the package to Foo2 as well?
        What you are doing at the moment isn't object-oreinted code, so you should call the subroutine simply with Foo2::bar. Or just simply "bar()" because you exported "bar" from pacakge Foo2 into the local namespace of the script that uses Foo2.