X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FText%2FAbbrev.pm;h=08143fea8fb19696709ce4f5298c4d600bac2fdb;hb=bb2cbcd1ec679f28ec7f1a4f685707a368d32502;hp=77370d37c3947eaf31d3f3f06069044848e2301b;hpb=a0d0e21ea6ea90a22318550944fe6cb09ae10cda;p=p5sagit%2Fp5-mst-13.2.git diff --git a/lib/Text/Abbrev.pm b/lib/Text/Abbrev.pm index 77370d3..08143fe 100644 --- a/lib/Text/Abbrev.pm +++ b/lib/Text/Abbrev.pm @@ -1,37 +1,83 @@ package Text::Abbrev; -require 5.000; +require 5.005; # Probably works on earlier versions too. require Exporter; +our $VERSION = '1.00'; + +=head1 NAME + +abbrev - create an abbreviation table from a list + +=head1 SYNOPSIS + + use Text::Abbrev; + abbrev $hashref, LIST + + +=head1 DESCRIPTION + +Stores all unambiguous truncations of each element of LIST +as keys in the associative array referenced by C<$hashref>. +The values are the original list elements. + +=head1 EXAMPLE + + $hashref = abbrev qw(list edit send abort gripe); + + %hash = abbrev qw(list edit send abort gripe); + + abbrev $hashref, qw(list edit send abort gripe); + + abbrev(*hash, qw(list edit send abort gripe)); + +=cut + @ISA = qw(Exporter); @EXPORT = qw(abbrev); # Usage: -# &abbrev(*foo,LIST); +# abbrev \%foo, LIST; # ... # $long = $foo{$short}; sub abbrev { - local(*domain) = shift; - @cmp = @_; - %domain = (); - foreach $name (@_) { - @extra = split(//,$name); - $abbrev = shift(@extra); - $len = 1; - foreach $cmp (@cmp) { - next if $cmp eq $name; - while (substr($cmp,0,$len) eq $abbrev) { - $abbrev .= shift(@extra); - ++$len; + my ($word, $hashref, $glob, %table, $returnvoid); + + if (ref($_[0])) { # hash reference preferably + $hashref = shift; + $returnvoid = 1; + } elsif (ref \$_[0] eq 'GLOB') { # is actually a glob (deprecated) + $hashref = \%{shift()}; + $returnvoid = 1; + } + %{$hashref} = (); + + WORD: foreach $word (@_) { + for (my $len = (length $word) - 1; $len > 0; --$len) { + my $abbrev = substr($word,0,$len); + my $seen = ++$table{$abbrev}; + if ($seen == 1) { # We're the first word so far to have + # this abbreviation. + $hashref->{$abbrev} = $word; + } elsif ($seen == 2) { # We're the second word to have this + # abbreviation, so we can't use it. + delete $hashref->{$abbrev}; + } else { # We're the third word to have this + # abbreviation, so skip to the next word. + next WORD; } } - $domain{$abbrev} = $name; - while (@extra) { - $abbrev .= shift(@extra); - $domain{$abbrev} = $name; - } + } + # Non-abbreviations always get entered, even if they aren't unique + foreach $word (@_) { + $hashref->{$word} = $word; + } + return if $returnvoid; + if (wantarray) { + %{$hashref}; + } else { + $hashref; } } 1; -