⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 class.pm

📁 外国人写的Perl搜索引擎程序
💻 PM
字号:
package KinoSearch::Util::Class;use strict;use warnings;use KinoSearch::Util::ToolSet;use KinoSearch::Util::VerifyArgs qw( verify_args kerror );sub new {    my $class = shift;    # leave the rest of @_ intact.    # find a defaults hash and verify args    $class = ref($class) || $class;    my $defaults;    {        no strict 'refs';        $defaults = \%{ $class . '::instance_vars' };    }    if ( !verify_args( $defaults, @_ ) ) {        # if a user-based subclass, find KinoSearch parent class and verify.        my $kinoclass = _traverse_at_isa($class);        confess kerror() unless $kinoclass;        {            no strict 'refs';            $defaults = \%{ $kinoclass . '::instance_vars' };        }        confess kerror() unless verify_args( $defaults, @_ );    }    # merge var => val pairs into new object, call customizable init routine    my $self = bless { %$defaults, @_ }, $class;    $self->init_instance;    return $self;}# Walk @ISA until a parent class starting with 'KinoSearch::' is found.sub _traverse_at_isa {    my $orig = shift;    {        no strict 'refs';        my $at_isa = \@{ $orig . '::ISA' };        for my $parent (@$at_isa) {            return $parent if $parent =~ /^KinoSearch::/;            my $grand_parent = _traverse_at_isa($parent);            return $grand_parent if $grand_parent;        }    };    return '';}sub init_instance { }sub init_instance_vars {    my $package = shift;    no strict 'refs';    no warnings 'once';    my $first_isa = ${ $package . '::ISA' }[0];    %{ $package . '::instance_vars' }        = ( %{ $first_isa . '::instance_vars' }, @_ );}sub ready_get_set {    ready_get(@_);    ready_set(@_);}sub ready_get {    my $package = shift;    no strict 'refs';    for my $member (@_) {        *{ $package . "::get_$member" } = sub { return $_[0]->{$member} };    }}sub ready_set {    my $package = shift;    no strict 'refs';    for my $member (@_) {        *{ $package . "::set_$member" } = sub { $_[0]->{$member} = $_[1] };    }}=for Rationale:KinoSearch is not thread-safe.  Among other things, the C-struct-based classescause segfaults or bus errors when their data gets double-freed by DESTROY.Therefore, CLONE dies with a user-friendly error message before that happens.=cutsub CLONE {    my $package = shift;    die(      "CLONE invoked by package '$package', indicating that threads "            . "or Win32 fork were initiated, but KinoSearch is not thread-safe"    );}sub abstract_death {    my ( undef, $filename, $line, $methodname ) = caller(1);    die "ERROR: $methodname', called at $filename line $line, is an "        . "abstract method and must be defined in a subclass";}sub unimplemented_death {    my ( undef, $filename, $line, $methodname ) = caller(1);    die "ERROR: $methodname, called at $filename line $line, is "        . "intentionally unimplemented in KinoSearch, though it is part "        . "of Lucene";}sub todo_death {    my ( undef, $filename, $line, $methodname ) = caller(1);    die "ERROR: $methodname, called at $filename line $line, is not "        . "implemented yet in KinoSearch, but is on the todo list";}1;__END__=head1 NAMEKinoSearch::Util::Class - class building utility=head1 PRIVATE CLASSThis is a private class and the interface may change radically and withoutwarning.  Do not use it on its own.=head1 SYNOPSIS    package KinoSearch::SomePackage::SomeClass;    use base qw( KinoSearch::Util::Class );        BEGIN {        __PACKAGE__->init_instance_vars(            # constructor params / members            foo => undef,            bar => {},            # members            baz => {},        );    }=head1 DESCRIPTIONKinoSearch::Util::Class is a class-building utility a laL<Class::Accessor|Class::Accessor>, L<Class::Meta|Class::Meta>, etc.  Itprovides four main services:=over=item 1 A mechanism for inheriting instance variable declarations.=item 2 A constructor with basic argument checking.=item 3Manufacturing of get_xxxx and set_xxxx methods.=item 4 Convenience methods which help in defining abstract classes.=back=head1 VARIABLES=head2 %instance_varsThe %instance_vars hash, which is always a package global, serves as atemplate for the creation of a hash-based object.  It is built up from all the%instance_vars hashes in the module's parent classes, usinginit_instance_vars().  Key-value pairs in an %instance_vars hash are labeled as "constructor params"and/or "members".  Items which are labeled as constructor params can be usedas arguments to new().    BEGIN {        __PACKAGE__->init_instance_vars(            # constructor params / members            foo => undef,            bar => 10,            # members            baz => '',        );    }        # ok: specifies foo, uses default for bar, derives baz    my $object = __PACKAGE__->new( foo => $foo );    # not ok: baz isn't a constructor param    my $object = __PACKAGE__->new( baz => $baz );    # ok if a parent class defines boffo as a constructor param    my $object = __PACKAGE__->new(         foo   => $foo,        boffo => $boffo,    );%instance_vars may only contain scalar values, as the defaults are mergedinto the object using a shallow copy.init_instance_vars() must be called from within a BEGIN block and before anyC<use> directives load a child class -- if children are born before theirparents, inheritance gets screwed up.=head1 METHODS=head2 newA generic constructor with basic argument checking.  new() expects hash-stylelabeled parameters; the label names must be present in the %instance_varshash, or it will croak().After verifying the labeled parameters, new() merges %instance_vars and @_into a new object.  It then calls $self->init_instance() before returning theblessed reference.=head2 init_instance    $self->init_instance();Perform customized initialization routine.  By default, this is a no-op.=head2 init_instance_vars    BEGIN {        __PACKAGE__->init_instance_vars(            a_safe_variable_name_that_wont_clash => 1,            freep_warble                         => undef,        );    }Package method only.  Creates a package global %instance_vars hash in thepassed in package which consists of the passed in arguments plus all thekey-value pairs in the parent class's %instance_vars hash.=head2 ready_get_set ready_get ready_set    # create get_foo(), set_foo(), get_bar(), set_bar() in __PACKAGE__    BEGIN { __PACKAGE__->ready_get_set(qw( foo bar )) };Mass manufacture getters and setters.  The setters do not return a meaningfulvalue.=head2 abstract_death unimplemented_death todo_death    sub an_abstract_method      { shift->abstract_death }    sub an_unimplemented_method { shift->unimplemented_death }    sub maybe_someday           { shift->todo_death }These are just different ways to die(), and are of little interest until yourparticular application comes face to face with one of them.  abstract_death indicates that a method must be defined in a subclass.unimplemented_death indicates a feature/function that will probably not beimplemented.  Typically, this would appear for a sub that a developerintimately familiar with Lucene would expect to find.todo_death indicates a feature that might get implemented someday.=head1 COPYRIGHTCopyright 2005-2007 Marvin Humphrey=head1 LICENSE, DISCLAIMER, BUGS, etc.See L<KinoSearch|KinoSearch> version 0.163.=cut

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -