Perl Objects Aktuell Seminare Reports Homepage Software
printer / text mode version
university-logo
draheim
@informatik.hu-berlin.de

Reports
- postindustr.CC
- XML/Ti Report
- pTA StudienArbeit  .
- sch_llf study
- Geschichte des PC

TechDocs
- Perl Objects
- Installing Oracle
- shell cmds in python
- Using css for xml
    defs   tricks
- Unsafe mono  [x]  !
- Docbook Manpages
- Java Bean   Code
rpm-suse
 
- schema-mappingen
  ig cv hg re dv ev
  zz mk pr
- java problemsen
  lang swing ext gtk jjtree xul
 
boot
-grub-netboot
-grub-gtk
-partclone freshmeat
-partimage links
 
-releaseuploader


sitemap


-guidod-pygtk
sitemap             *offsite link

2004-12-02
(C) Guido Draheim
guidod@gmx.de

 
generated by mksite.sh

Howto Make a New Perl Object (techdoc)

 
my %obj = ( item => "foo" );
my $object = \%obj;

given
- my $object = { item => "foo" };

then these are the same:
- $$object{item}
- $object->{item}

SUB NEW constructor

associate methods by bless:
- bless $object, "packagename";

and remember that any file can
define symbols for any package,
(it's just a prefix name after all)

if there exists
- sub packagename::mymethod { .. }

then one can call the method by
- $object->mymethod(...);

if "bless" is used with $object alone then the current packagename is used
which is used in package-local constructors:


package mypackage;

sub new
{
    my $self = { };
    bless $self;
    return $self;
}

For the reason of inheritance, the
following template should be used:

sub new
{
   my $invocant = shift; # may be a subclass
   my $class = ref ($invocant) || $invocant;
   my $self = { a => "00" }; $self->{b} = "01";
   bless $self, $class;
   return $self;
}

remember the method call inversion,
print STDERR "foo"
is actually identical with:
$STDERR->print("foo")

While for small structures the following shorthand can be useful:

sub new {
    return bless
      { a => "00",
        b => "01" },
      "methodpackage";
}

For inheritance there is a shorthand available which assumes the base class are defined in their own module file which will be "require":


package mypackage;
use base ("basepackage", "secondarypackage");

which is equivalent to

package mypackage;
BEGIN {
    @ISA = ("basepackage", "secondarypackage");
    require basepackage;
    require secondarypackage;
}

METHOD CALLS

Method calls work just as expected as they will receive the lefthand side of a "->" as the first argument:

sub foo # $self @args
{
  my ($self,$args,$else) = @_;
  $self->{id} += 1;
}
sub bar # @args
{
   my ($args,$else) = @_;
   $obj->foo ($args, $else);
}

The "new" constructor does also receive a first object being the packagname.... if it is called with its prefix. The template code above allows to call "new" with either (a) statically with the package name prefix or (b) dynamically as a method of an existing object - the "ref" will extract the packagename for us.

sub create # with args and hint
{
   my $obj = new mypackage::(@_);
   $obj->{extrahint} = "foo";
   return $obj;
}
sub nextobject # clone it
{
   my ($old,$args) = @_;
   my $obj = $old->new($args);
   $obj->{id} += 1;
   return $obj;
}

I do strongly recommend to call constructors with the "::" attached to the packagename even that it is optional - if you forgot to import then it might be a variable and you will not be warned about. Therefore it should be always "new packagename::()".

METHOD PROTOTYPES

Method prototypes are not what would be thought of - instead they denote casting on the argument list which is an entirely different concept. There is only an error if the cast would fail. All of "$" "@", "%" "*" do cast to those data types - remember that nonscalar casts look like "@{ $arrayref }" and the scalar cast looks like "scalar @array".

The backslash has a special meaning as it enforces the following argument to be only of that data type firsthand and referenced right away. So that you can now have
- sub mypush (\@@) { }

being called like
- mypush @array, @other;

and remember that the last @ or % in a prototype will consume all the rest of the arguments just like with
- my ($array, $other) = @_;

Last not least, a ";" is put between required arguments and optional arguments, i.e. "$;$" can have one or two scalar arguments.

MODULES


- require modulename;
- require "modulename.pm";

The difference: There is none but that the bareword "modulename" is reserved as a packagetype in the first version.


- require modulename;
- use modulename;

The difference: instead of loading at runtime (in version 1) the loading is done at compiletime (in version 2), i.e. like
- BEGIN { require modulename; }

The import of package local symbols the global/current namespace is done by a list after "use" like
- use modulename (a,b,c);

if the list is ommitted then modulename's @EXPORT variable is used and if no such variable exists then all the names in the module must be accessed fully qualified.


package mymodule;
our @EXPORT = qw/functional $variable/;

The extract above is what I have learned from the "Camel Book", (Wall/Christiansen/Orwant "Programming Perl") plus some hands-on experience.