Search     or:     and:
 LINUX 
 Language 
 Kernel 
 Package 
 Book 
 Test 
 OS 
 Forum 
 iakovlev.org 
 Languages
 С
 GNU С Library 
 Qt 
 STL 
 Threads 
 C++ 
 Samples 
 stanford.edu 
 ANSI C
 Libs
 LD
 Socket
 Pusher
 Pipes
 Encryption
 Plugin
 Inter-Process
 Errors
 Deep C Secrets
 C + UNIX
 Linked Lists / Trees
 Asm
 Perl
 Python
 Shell
 Erlang
 Go
 Rust
 Алгоритмы
NEWS
Последние статьи :
  Тренажёр 16.01   
  Эльбрус 05.12   
  Алгоритмы 12.04   
  Rust 07.11   
  Go 25.12   
  EXT4 10.11   
  FS benchmark 15.09   
  Сетунь 23.07   
  Trees 25.06   
  Apache 03.02   
 
TOP 20
 Linux Kernel 2.6...5175 
 Trees...950 
 Максвелл 3...877 
 Go Web ...832 
 William Gropp...814 
 Ethreal 3...792 
 Gary V.Vaughan-> Libtool...782 
 Ethreal 4...776 
 Rodriguez 6...771 
 Ext4 FS...766 
 Clickhouse...765 
 Steve Pate 1...762 
 Ethreal 1...747 
 Secure Programming for Li...737 
 C++ Patterns 3...724 
 Ulrich Drepper...704 
 Assembler...699 
 DevFS...670 
 Стивенс 9...657 
 MySQL & PosgreSQL...639 
 
  01.01.2024 : 3621733 посещений 

iakovlev.org

FAQ

Все материалы взяты с сайта www.cpan.org .

Как инсталировать CPAN Perl modules?

Наберите perl -MCPAN -e 'install Chocolate::Belgian'. По ссылке CPAN.pm documentation можно найти более подробное описание .


Как удалить установленные Perl modules?

Для этого используйте стандартные модули ExtUtils::Installed и ExtUtils::Packlist и смотрите пример ниже :


 #!/usr/local/bin/perl -w
 
 use ExtUtils::Packlist;
 use ExtUtils::Installed;
 
 $ARGV[0] or die "Usage: $0 Module::Name\n";
 
 my $mod = $ARGV[0]; 
 
 my $inst = ExtUtils::Installed->new();
 
     foreach my $item (sort($inst->files($mod))) {
              print "removing $item\n";
              unlink $item;
           }
 
 my $packfile = $inst->packlist($mod)->packlist_file();
           print "removing $packfile\n";
           unlink $packfile;
   
 

Как мне определить - какие модули уже установлены ?

  • perldoc perllocal

    Каждый устанавливаемый модуль добавляет информацию о себе в файл perllocal.pod который лежит в районе /usr/local/lib/perl5/version number/architecture/ . Информацию о системных перловых каталогах можно извлечь с помощью perl -V.

    =head2 Wed May 12 13:42:53 1999: C<Module> L<Data::Dumper>
     
     =over 4
     
     =item *
     
     C<installed into: /usr/local/lib/perl5/5.00503>
     
     =item *
     
     C<LINKTYPE: dynamic>
     
     =item *
     
     C<VERSION: 2.101>
     
     =item *
     
     C<EXE_FILES: >
     
     =back
     
  • Использование ExtUtils::Installed
    
     #!/usr/local/bin/perl
     
     use ExtUtils::Installed;
     my $instmod = ExtUtils::Installed->new();
     foreach my $module ($instmod->modules()) {
     my $version = $instmod->version($module) || "???";
            print "$module -- $version\n";
     }
     

    что выведет примерно следующее

    
     Apache::DBI -- 0.87
     Apache::DBILogConfig -- 0.01
     Apache::DBILogger -- 0.93
     AppConfig -- 1.52
     Archive::Tar -- 0.22
     BerkeleyDB -- 0.06
     CGI -- 2.74
     CPAN -- 1.59
     CPAN::WAIT -- 0.27
     Catalog -- 1.00
     Compress::Zlib -- 1.11
     Config::IniFiles -- 2.14
     Convert::BER -- 1.26
     Coy -- ???
     Crypt::Rot13 -- 0.04
     Crypt::SSLeay -- 0.16
     DBI -- 1.14
     [.....]
     

  • Как мне определить - работает ли данный модуль на моей операционной системе?

    Зайдите на http://testers.cpan.org/ - там приведен список модулей и соответственно работающих платформ для них.


    Как вручную установить модуль в private/non-standard directory?

    Выставьте переметры PREFIX и LIB перед запуском Makefile.PL. Например:

     foo@barbell$ perl Makefile.PL LIB=/home/foobar/mylib PREFIX=/home/foobar/mylib
     

    Как использовать модули , поставленные в private/non-standard directory?

    • foo@barbell$ setenv PERL5LIB /path/to/module - из командной строки
    • use lib qw(/path/to/module); прописано в хидере скрипта.
    • foo@barbell$ perl -I/path/to/module

    При этом каждый вариант добавляет /path/to/module в @INC.


    Где бы мне найти Perl scripts?


    Perl - журналы


    Perl courses/training/on-line tutorials?

    Training

    On-line Tutorials


    Что такое Perl?

    Perl - высокоуровневый язык программирования , написанный Larry Wall (и не только). В основном он унаследовал свойства языка C и в меньшей степени - sed,awk,shell. Работа с процессами,файлами, манипуляции с текстом позволяют легко работать с системными утилитами, доступом к базе данных , графическим программированием , сетью, вебом. Этот язык особенно популярен у системных админов , веб-программистов , научных работников и т.д.

    Кто поддерживает Perl? Кто разрабатывает его? Почему он бесплатен ?

    Исторически сложившиеся традиции интернета , а также индивидуальные особенности самого Larry Wall сделали перл бесплатным и открытым . Perl поддерживается его пользователями. Сore team (Perl Porters) - группа высоко альтруистичных индивидуумов :-) обьединенных целью создания бесплатного продукта . Историю развития ядра Perl можно посмотреть на http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/ и http://archive.develooper.com/perl5-porters@perl.org/ или nntp://nntp.perl.org/perl.perl5.porters или http://nntp.perl.org/group/perl.perl5.porters , faq - http://simon-cozens.org/writings/p5p-faq , или можно подписаться на рассылку по адресу perl5-porters-request@perl.org (an empty message with no subject is fine).

    В чем разница между perl4, perl5, perl6?

    perl4 - это прошлое, perl5 - настоящее, perl6 - это будущее.

    Текущая версия на 2005-й год - perl5, реализована аж в 1994. Она совместима с perl4 (1991),но имеет такие фичи , как ссылки , модули и т.д.

    Разработка Perl6 стартовала в 2002 и до сих пор в процессе. Больше можно узнать на http://dev.perl.org/perl6/ .

    Труден ли Perl в изучении?

    Нет . Если вы раньше писали программы на С , или shell , или даже бэйсике , то освоить его будет нетрудно.

    Одним из главных свойств Perl является аксиома - "любую задачу всегда можно сделать более чем одним способом".

    Поскольку Perl - язык интерпретируемый , скрипты можно тестировать без компиляции.

    Ну и конечно огромным плюсом в изучении Perl является сам факт Unix-experience.


    Perl Books

    	Programming Perl (the "Camel Book"):
     	by Larry Wall, Tom Christiansen, and Jon Orwant
     	ISBN 0-596-00027-8  [3rd edition July 2000]
     	http://www.oreilly.com/catalog/pperl3/
     	(English, translations to several languages are also available)
     

    	The Perl Cookbook (the "Ram Book"):
     	by Tom Christiansen and Nathan Torkington,
     	    with Foreword by Larry Wall
     	ISBN 0-596-00313-7 [2nd Edition August 2003]
     	http://www.oreilly.com/catalog/perlckbk2/
     

    	Learning Perl (the "Llama Book")
     	by Randal L. Schwartz and Tom Phoenix
     	ISBN 0-596-00132-0 [3rd edition July 2001]
     	http://www.oreilly.com/catalog/lperl3/
     

    	Learning Perl Objects, References, and Modules (the "Alpaca Book")
     	by Randal L. Schwartz, with Tom Phoenix (foreword by Damian Conway)
     	ISBN 0-596-00478-8 [1st edition June 2003]
     	http://www.oreilly.com/catalog/lrnperlorm/
     

    	Perl: The Programmer's Companion
     	by Nigel Chapman
     	ISBN 0-471-97563-X [1997, 3rd printing Spring 1998]
     	http://www.wiley.com/compbooks/catalog/97563-X.htm
     	http://www.wiley.com/compbooks/chapman/perl/perltpc.html (errata etc)
     
    References
    	Programming Perl
     	by Larry Wall, Tom Christiansen, and Jon Orwant
     	ISBN 0-596-00027-8 [3rd edition July 2000]
     	http://www.oreilly.com/catalog/pperl3/
     
     	Perl 5 Pocket Reference
     	by Johan Vromans
     	ISBN 0-596-00032-4 [3rd edition May 2000]
     	http://www.oreilly.com/catalog/perlpr3/
     
     	Perl in a Nutshell
     	by Ellen Siever, Stephan Spainhour, and Nathan Patwardhan
     	ISBN 1-56592-286-7 [1st edition December 1998]
     	http://www.oreilly.com/catalog/perlnut/
     
    Tutorials
    	Beginning Perl
     	by James Lee
     	ISBN 1-59059-391-X [2nd edition August 2004]
     	http://apress.com/book/bookDisplay.html?bID=344
     
     	Elements of Programming with Perl
     	by Andrew L. Johnson
     	ISBN 1-884777-80-5 [1st edition October 1999]
     	http://www.manning.com/Johnson/
     
     	Learning Perl
     	by Randal L. Schwartz and Tom Phoenix
     	ISBN 0-596-00132-0 [3rd edition July 2001]
     	http://www.oreilly.com/catalog/lperl3/
     
     	Learning Perl Objects, References, and Modules
     	by Randal L. Schwartz, with Tom Phoenix (foreword by Damian Conway)
     	ISBN 0-596-00478-8 [1st edition June 2003]
     	http://www.oreilly.com/catalog/lrnperlorm/
     
     	Learning Perl on Win32 Systems
     	by Randal L. Schwartz, Erik Olson, and Tom Christiansen,
     	    with foreword by Larry Wall
     	ISBN 1-56592-324-3 [1st edition August 1997]
     	http://www.oreilly.com/catalog/lperlwin/
     
     	Perl: The Programmer's Companion
     	by Nigel Chapman
     	ISBN 0-471-97563-X [1997, 3rd printing Spring 1998]
     	http://www.wiley.com/compbooks/catalog/97563-X.htm
     	http://www.wiley.com/compbooks/chapman/perl/perltpc.html (errata etc)
     
     	Cross-Platform Perl
     	by Eric Foster-Johnson
     	ISBN 1-55851-483-X [2nd edition September 2000]
     	http://www.pconline.com/~erc/perlbook.htm
     
     	MacPerl: Power and Ease
     	by Vicki Brown and Chris Nandor,
     	    with foreword by Matthias Neeracher
     	ISBN 1-881957-32-2 [1st edition May 1998]
     	http://www.macperl.com/ptf_book/
     
    Task-Oriented
    	Writing Perl Modules for CPAN
     	by Sam Tregar
     	ISBN 1-59059-018-X [1st edition Aug 2002]
     	http://apress.com/book/bookDisplay.html?bID=14
     
     	The Perl Cookbook
     	by Tom Christiansen and Nathan Torkington
     	    with foreword by Larry Wall
     	ISBN 1-56592-243-3 [1st edition August 1998]
     	http://www.oreilly.com/catalog/cookbook/
     
     	Effective Perl Programming
     	by Joseph Hall
     	ISBN 0-201-41975-0 [1st edition 1998]
     	http://www.awl.com/
     
     	Real World SQL Server Administration with Perl
     	by Linchi Shea
     	ISBN 1-59059-097-X [1st edition July 2003]
     	http://apress.com/book/bookDisplay.html?bID=171
     
    Special Topics
    	Perl 6 Now: The Core Ideas Illustrated with Perl 5
     	by Scott Walters
     	ISBN 1-59059-395-2 [1st edition December 2004
     	http://apress.com/book/bookDisplay.html?bID=355
     
     	Mastering Regular Expressions
     	by Jeffrey E. F. Friedl
     	ISBN 0-596-00289-0 [2nd edition July 2002]
     	http://www.oreilly.com/catalog/regex2/
     
     	Network Programming with Perl
     	by Lincoln Stein
     	ISBN 0-201-61571-1 [1st edition 2001]
     	http://www.awlonline.com/
     
     	Object Oriented Perl
     	Damian Conway
     	    with foreword by Randal L. Schwartz
     	ISBN 1-884777-79-1 [1st edition August 1999]
     	http://www.manning.com/Conway/
     
     	Data Munging with Perl
     	Dave Cross
     	ISBN 1-930110-00-6 [1st edition 2001]
     	http://www.manning.com/cross
     
     	Mastering Perl/Tk
     	by Steve Lidie and Nancy Walsh
     	ISBN 1-56592-716-8 [1st edition January 2002]
     	http://www.oreilly.com/catalog/mastperltk/
     
     	Extending and Embedding Perl
     	by Tim Jenness and Simon Cozens
     	ISBN 1-930110-82-0 [1st edition August 2002]
     	http://www.manning.com/jenness
     
     	Perl Debugger Pocket Reference
     	by Richard Foley
     	ISBN 0-596-00503-2 [1st edition January 2004]
     	http://www.oreilly.com/catalog/perldebugpr/
     

    Perl из командной строки ?

    Запуск интерпретатора из командной строки :

        perl -de 42
     

    В таком стиле можно например использовать опции интерактивного дебага .

    Установленные модули на системе ?

    Используйте ExtUtils::Installed модуль .

    	use ExtUtils::Installed;
     
     	my $inst    = ExtUtils::Installed->new();
     	my @modules = $inst->modules();
     

    Если нужно вывести имена всех модулей - используйте File::Find::Rule:

    	use File::Find::Rule;
     
     	my @files = File::Find::Rule->file()->name( '*.pm' )->in( @INC );
     

    Или так :

        use File::Find;
         my @files;
     
         find sub { push @files, $File::Find::name if -f _ && /\.pm$/ },
              @INC;
     
     	print join "\n", @files;
     

    Проверка наличия конкретного модуля :

    	prompt% perldoc Module::Name
     

    debug Perl programs?

    Пробовали use warnings или -w?

    Или use strict? Эта директива отбивает охоту от использования неправильных ссылок , приучает к использованию префикса my, our, use vars.

    Как проверить возвращаемые значения при system call?

      open(FH, "> /etc/cantwrite")
         or die "Couldn't write to /etc/cantwrite: $!\n";
     

    profile Perl programs ?

    Используйте модуль Benchmark.pm.

      use Benchmark;
     
       @junk = `cat /etc/motd`;
       $count = 10_000;
     
       timethese($count, {
                 'map' => sub { my @a = @junk;
     			   map { s/a/b/ } @a;
     			   return @a },
                 'for' => sub { my @a = @junk;
     			   for (@a) { s/a/b/ };
     			   return @a },
                });
     

    Будет распечатано :

      Benchmark: timing 10000 iterations of for, map...
              for:  4 secs ( 3.97 usr  0.01 sys =  3.98 cpu)
              map:  6 secs ( 4.97 usr  0.00 sys =  4.97 cpu)
     

    Написание бенч-марков , вообще говоря , довольно неблагодарное занятие .

    Как ускорить программу на Perl ?

    Начинайте с алгоритма . Советы по этому поводу можно найти в книге Jon Bentley's Programming Pearls . Использование benchmarking и profile также может выявить узкие места в программе .

    Другой подход - использование autoload Perl code. Смотрите модули AutoSplit и AutoLoader . Третий подход - использование С-кода (например , модуль PDL в CPAN).

    Как сделать , чтобы Perl-программа не потребляла много памяти ?

    Если сравнить затраты на память для переменных , массивов в перл и в С , то вывод не в пользу первого .

    Но можно кое-что придумать . Например , массив из 1000 переменных типа bool занимает 20 килобайт , но его можно трансформировать в 125-байтный вектор. Модуль Tie::SubstrHash может помочь для определенных типов структур .

    • Рассмотрим пример

      	#
       	# Правильный подход
       	#
       	while (<FILE>) {
       	   # ...
       	}
       

      вместо:

      	#
       	# неправильный подход
       	#
       	@data = <FILE>;
       	foreach (@data) {
       	    # ...
       	}
       
    • Grep

      Для больших файлов вместо :

              @wanted = grep {/pattern/} <FILE>;
       

      делайте так :

              while (<FILE>) {
                       push(@wanted, $_) if /pattern/;
               }
       
    • Пример квотирования

      Избегайте избыточного квотирования - вместо :

              my $copy = "$large_string";
       

      которое сделает 2 копии $large_string , делайте так :

              my $copy = $large_string;
       

      Для больших массивов более эффективно :

              {
                       local $, = "\n";
                       print @big_array;
               }
       

      чем

              print join "\n", @big_array;
       

      или

              {
                       local $" = "\n";
                       print "@big_array";
               }
       

    • Параметры по ссылке

      Массивы и хэши нужно передавать по ссылке , а не по значению .

      Корректно ли возвращать ссылку на локальную переменную ?

          sub makeone {
       	my @a = ( 1 .. 10 );
       	return \@a;
           }
       
           for ( 1 .. 10 ) {
               push @many, makeone();
           }
       
           print $many[4][5], "\n";
       
           print "@many\n";
       

      Могу ли я откомпилировать Perl программу ?

      Вообще говоря , нет .

      Хотя есть решения - например (http://www.activestate.com/Products/Perl_Dev_Kit/) от ActiveState компилит байт-код , в частности по винду .

      Perl2Exe (http://www.indigostar.com/perl2exe.htm) - тоже под винду .

      Perl и командная строка ?

          # sum first and last fields
           perl -lane 'print $F[0] + $F[-1]' *
       
           # identify text files
           perl -le 'for(@ARGV) {print if -f && -T _}' *
       
           # remove (most) comments from C program
           perl -0777 -pe 's{/\*.*?\*/}{}gs' foo.c
       
           # make file a month younger than today, defeating reaper daemons
           perl -e '$X=24*60*60; utime(time(),time() + 30 * $X,@ARGV)' *
       
           # find first unused uid
           perl -le '$i++ while getpwuid($i); print $i'
       
           # display reasonable manpath
           echo $PATH | perl -nl -072 -e '
       	s![^/+]*$!man!&&-d&&!$s{$_}++&&push@m,$_;END{print"@m"}'
       

      CGI / Web programming на Perl?

      	http://www.perl.org/CGI_MetaFAQ.html
       

      Data: Numbers

      Почему я получаю 19.9499999999999 вместо 19.95?

      	printf "%.2f", 10/3;
       
       	my $number = sprintf "%.2f", 10/3;
       

      8-ричная система счисления ?

      Perl понимает 8-ричную и 16-ную системы счисления . В первом случае число должно начинаться с "0" , во втором с "0x". Для конвертации в 10-ную систему можно использовать oct() и hex() . Для конвертации из 10 в 8 можно использовать "%o" или "%O" sprintf() форматы.

      Типичная ошибка :

          chmod(644,  $file);	# WRONG
           chmod(0644, $file);	# right
       

      Функции round() , ceil() , floor() , Trig ?

      Для округления нужно использовать sprintf() или printf() .

          printf("%.3f", 3.1415926535);	# prints 3.142
       

      Модуль POSIX имплементирует ceil(), floor(), и ряд других функций.

          use POSIX;
           $ceil   = ceil(3.5);			# 4
           $floor  = floor(3.5);			# 3
       

      Пример :

          for ($i = 0; $i < 1.01; $i += 0.05) { printf "%.1f ",$i}
       
           0.0 0.1 0.1 0.2 0.2 0.2 0.3 0.3 0.4 0.4 0.5 0.5 0.6 0.7 0.7
           0.8 0.8 0.9 0.9 1.0 1.0
       

      Операции с массивами целых чисел ?

      Вызов функции для каждого элемента в массиве :

          @results = map { my_func($_) } @array;
       

      Например:

          @triple = map { 3 * $_ } @single;
       

      То же самое , но игнорировать результат :

          foreach $iterator (@array) {
               some_func($iterator);
           }
       

      Вызов для диапазона чисел :

          @results = map { some_func($_) } (5 .. 25);
       

      Или так :

          for my $i (5 .. 500_005) {
               push(@results, some_func($i));
           }
       

      will not create a list of 500,000 integers.

      Случайные числа между X и Y?

          my $number = 10 + int rand( 15-10+1 );
       

      Пример : random_int_in(50,120).

         sub random_int_in ($$) {
            my($min, $max) = @_;
             # Assumes that the two arguments are integers themselves!
            return $min if $min == $max;
            ($min, $max) = ($max, $min)  if  $min > $max;
            return $min + int rand(1 + $max - $min);
          }
       

      Data: Dates

      День недели или года ?

          $day_of_year = (localtime)[7];
       

      Модуль POSIX :

      	use POSIX qw/strftime/;
       	my $day_of_year  = strftime "%j", localtime;
       	my $week_of_year = strftime "%W", localtime;
       

      Модуль Time::Local :

      	use POSIX qw/strftime/;
       	use Time::Local;
       	my $week_of_year = strftime "%W",
       		localtime( timelocal( 0, 0, 0, 18, 11, 1987 ) );
       

      Модуль Date::Calc :

      	use Date::Calc;
       	my $day_of_year  = Day_of_Year(  1987, 12, 18 );
       	my $week_of_year = Week_of_Year( 1987, 12, 18 );
       

      Вчерашняя дата ?

      	use DateTime;
       
       	my $yesterday = DateTime->now->subtract( days => 1 );
       
       	print "Yesterday was $yesterday\n";
       

      Модуль Date::Calc :

      	use Date::Calc qw( Today_and_Now Add_Delta_DHMS );
       
       	my @date_time = Add_Delta_DHMS( Today_and_Now(), -1, 0, 0, 0 );
       
       	print "@date\n";
       

      Data: Strings

      Удалить обратный слэш ?

          s/\\(.)/$1/g;
       

      Удалить дубликаты ?

          s/(.)\1/$1/g;
       
      	my $str = 'Haarlem';   # in the Netherlands
           $str =~ tr///cs;       # Now Harlem, like in New York
       

      matching/nesting ?

      Работающий пример :

          # $_ есть строка для парсинга
       
           @( = ('(','');
           @) = (')','');
           ($re=$_)=~s/((BEGIN)|(END)|.)/$)[!$3]\Q$1\E$([!$2]/gs;
           @$ = (eval{/$re/},$@!~/unmatched/i);
           print join("\n",@$[0..$#$]) if( $$[-1] );
       

      Реверс строки ?

          $reversed = reverse $string;
       

      Табуляция ?

          1 while $string =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e;
       

      Модуль Text::Tabs :

          use Text::Tabs;
           @expanded_lines = expand(@lines_with_tabs);
       

      Изменить N символов в строке ?

      Доступ к началу строки - substr().

      	$string = "Just another Perl Hacker";
           $first_char = substr( $string, 0, 1 );  #  'J'
       

      Для изменения произвольного куска строки эту функцию нужно использовать с 4 параметрами :

          substr( $string, 13, 4, "Perl 5.8.0" );
       

      Или :

          substr( $string, 13, 4 ) =  "Perl 5.8.0";
       

      Изменить один символ ?

      Например , нужно поменять "whoever" или "whomever" в "whosoever" или "whomsoever". $_ - изменяемая строка :

          $count = 0;
           s{((whom?)ever)}{
       	++$count == 5   	# is it the 5th?
       	    ? "${2}soever"	# yes, swap
       	    : $1		# renege and leave it there
           }ige;
       

      В цикле :

          $WANT = 3;
           $count = 0;
           $_ = "One fish two fish red fish blue fish";
           while (/(\w+)\s+fish\b/gi) {
               if (++$count == $WANT) {
                   print "The third fish is a $1 one.\n";
               }
           }
       

      Будет напечатано : "The third fish is a red one."

      Подсчитать количество одного символа в строке ?

      Например символ (X) с использованием tr///:

          $string = "ThisXlineXhasXsomeXx'sXinXit";
           $count = ($string =~ tr/X//);
           print "There are $count X characters in the string";
       

      Теперь другая задача - число отрицательных чисел :

          $string = "-9 55 48 -2 23 -76 4 14 -44";
           while ($string =~ /-\d+/g) { $count++ }
           print "There are $count negative numbers in the string";
       

      Или :

      	$count = () = $string =~ /-\d+/g;
       

      Регистр ?

      Первый символ каждого слова заглавным :

              $line =~ s/\b(\w)/\U$1/g;
       

      "don't do it" -> "Don'T Do It". Или :

          $string =~ s/ (
                        (^\w)    #at the beginning of the line
                          |      # or
                        (\s\w)   #preceded by whitespace
                          )
                       /\U$1/xg;
           $string =~ /([\w']+)/\u\L$1/g;
       

      Все символы заглавные :

              $line = uc($line);
       

      Первый символ слова заглавный , остальные - прописные :

              $line =~ s/(\w+)/\u\L$1/g;
       

      split ?

      Имеется строка слов - удалить из нее запятые :

      SAR001,"","Cimetrix,Inc","Bob Smith","CAM",N,8,1,0,7,"Error,Core Dumped"
       

      Решение :

           @new = ();
            push(@new, $+) while $text =~ m{
         "([^\"\\]*(?:\\.[^\"\\]*)*)",?  # groups the phrase inside the quotes
              | ([^,]+),?
              | ,
            }gx;
            push(@new, undef) if substr($text,-1,1) eq ',';
       

      Добавить пробел в начало и конец строки ?

      В 2 приема :

      	s/^\s+//;
       	s/\s+$//;
       

      В 1 прием :

      	s/^\s+|\s+$//g;
       

      Для мульти-строчных строк :

          $string =~ s/^\s+|\s+$//gm;
       

      Или так :

      	$string =~ s/^[\t\f ]+|[\t\f ]+$//mg;
       

      Шаблоны из повторов символов ?

          # Left padding a string with blanks (no truncation):
       	$padded = sprintf("%${pad_len}s", $text);
       	$padded = sprintf("%*s", $pad_len, $text);  # same thing
       
           # Right padding a string with blanks (no truncation):
       	$padded = sprintf("%-${pad_len}s", $text);
       	$padded = sprintf("%-*s", $pad_len, $text); # same thing
       
           # Left padding a number with 0 (no truncation):
       	$padded = sprintf("%0${pad_len}d", $num);
       	$padded = sprintf("%0*d", $pad_len, $num); # same thing
       
           # Right padding a string with blanks using pack (will truncate):
           $padded = pack("A$pad_len",$text);
       
          $padded = $pad_char x ( $pad_len - length( $text ) ) . $text;
           $padded = $text . $pad_char x ( $pad_len - length( $text ) );
       
          substr( $text, 0, 0 ) = $pad_char x ( $pad_len - length( $text ) );
           $text .= $pad_char x ( $pad_len - length( $text ) );
       

      Выделение подстрок в строке ?

          # determine the unpack format needed to split Linux ps output
           # arguments are cut columns
           my $fmt = cut2fmt(8, 14, 20, 26, 30, 34, 41, 47, 59, 63, 67, 72);
       
           sub cut2fmt {
       	my(@positions) = @_;
       	my $template  = '';
       	my $lastpos   = 1;
       	for my $place (@positions) {
       	    $template .= "A" . ($place - $lastpos) . " ";
       	    $lastpos   = $place;
       	}
       	$template .= "A*";
       	return $template;
           }
       

      Встроенная переменная в строке ?

      Есть строка :

          $text = 'this has a $foo in it and a $bar';
       
          eval { $text =~ s/(\$\w+)/$1/eeg };
           die if $@;
       

      Или так :

          %user_defs = (
       	foo  => 23,
       	bar  => 19,
           );
           $text =~ s/\$(\w+)/$user_defs{$1}/g;
       

      Неверный префикс "$vars"?

          print "$var";   	# BAD
           $new = "$old";   	# BAD
           somefunc("$var");	# BAD
       

      Правильно :

          print $var;
           $new = $old;
           somefunc($var);
       

      Неверно :

          func(\@array);
           sub func {
       	my $aref = shift;
       	my $oref = "$aref";  # WRONG
           }
       

      Пример :

          @lines = `command`;
           print "@lines";		# WRONG - extra blanks
           print @lines;		# right
       

      Data: Arrays

      Разница между списком и массивом ?

      Массив - array - имеет переменную длину . Список - list - нет .

      Удалить duplicate elements из массива ?

      (contributed by brian d foy)

      Используйте hash.

         my %hash   = map { $_, 1 } @array;
          # or a hash slice: @hash{ @array } = ();
          # or a foreach: $hash{$_} = 1 foreach ( @array );
       
          my @unique = keys %hash;
       
      	my @unique = ();
       	my %seen   = ();
       
       	foreach my $elem ( @array )
       		{
       		next if $seen{ $elem }++;
       		push @unique, $elem;
       		}
       

      Используя grep :

         my %seen = ();
          my @unique = grep { ! $seen{ $_ }++ } @array;
       

      Найти элемент в масстве ?

      С помощью хэша :

          @blues = qw/azure cerulean teal turquoise lapis-lazuli/;
           %is_blue = ();
           for (@blues) { $is_blue{$_} = 1 }
       

      Теперь можно проверить наличие $is_blue{$some_color}.

      Для массива целых чисел :

          @primes = (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31);
           @is_tiny_prime = ();
           for (@primes) { $is_tiny_prime[$_] = 1 }
           # or simply  @istiny_prime[@primes] = (1) x @primes;
       

      Теперь проверяем $is_tiny_prime[$some_number].

      Для чисел в диапазоне :

          @articles = ( 1..10, 150..2000, 2017 );
           undef $read;
           for (@articles) { vec($read,$_,1) = 1 }
       

      Теперь проверяем vec($read,$n,1) для $n.

          ($is_there) = grep /$whatever/, @array;
       

      Или так :

          $is_there = 0;
           foreach $elt (@array) {
       	if ($elt eq $elt_to_find) {
       	    $is_there = 1;
       	    last;
       	}
           }
           if ($is_there) { ... }
       

      Разница между 2-мя массивами или их пересечение ?

      И опять hash.

          @union = @intersection = @difference = ();
           %count = ();
           foreach $element (@array1, @array2) { $count{$element}++ }
           foreach $element (keys %count) {
       	push @union, $element;
       push @{ $count{$element} > 1 ? \@intersection : \@difference }, $element;
           }
       

      Равны ли 2 массива ?

          $are_equal = compare_arrays(\@frogs, \@toads);
       
           sub compare_arrays {
       	my ($first, $second) = @_;
       	no warnings;  # silence spurious -w undef complaints
       	return 0 unless @$first == @$second;
       	for (my $i = 0; $i < @$first; $i++) {
       	    return 0 if $first->[$i] ne $second->[$i];
       	}
       	return 1;
           }
       

      Для сложных структур используйте модуль CPAN FreezeThaw :

          use FreezeThaw qw(cmpStr);
           @a = @b = ( "this", "that", [ "more", "stuff" ] );
       
           printf "a and b contain %s arrays\n",
               cmpStr(\@a, \@b) == 0
       	    ? "the same"
       	    : "different";
       

      Для хэша :

          use FreezeThaw qw(cmpStr cmpStrHard);
       
           %a = %b = ( "this" => "that", "extra" => [ "more", "stuff" ] );
           $a{EXTRA} = \%b;
           $b{EXTRA} = \%a;
       
           printf "a and b contain %s hashes\n",
       	cmpStr(\%a, \%b) == 0 ? "the same" : "different";
       
           printf "a and b contain %s hashes\n",
       	cmpStrHard(\%a, \%b) == 0 ? "the same" : "different";
       

      Найти первый элемент массива , для которого выполняется условие ?

      Находится первый элемент "Perl" :

      	use List::Util qw(first);
       
       	my $element = first { /Perl/ } @array;
       

      Аналогично можно использовать List::Util:

      	my $found;
       	foreach ( @array )
       		{
       		if( /Perl/ ) { $found = $_; last }
       		}
       

      С помощью индекса :

      	my( $found, $index ) = ( undef, -1 );
       	for( $i = 0; $i < @array; $i++ )
       		{
       		if( $array[$i] =~ /Perl/ )
       			{
       			$found = $array[$i];
       			$index = $i;
       			last;
       			}
       		}
       

      linked lists?

      Вообще говоря , такие списки в перле не особо инужны , поскольку мы и сами с помощью pop , shift ,unshift можем делать с массивом все что нужно .

      Но если уж сильно надо :

          $node = {
               VALUE => 42,
               LINK  => undef,
           };
       

      Теперь пробежимся :

          print "List: ";
           for ($node = $head;  $node; $node = $node->{LINK}) {
               print $node->{VALUE}, " ";
           }
           print "\n";
       

      Добавление :

          my ($head, $tail);
           $tail = append($head, 1);       # grow a new head
           for $value ( 2 .. 10 ) {
               $tail = append($tail, $value);
           }
       
           sub append {
               my($list, $value) = @_;
               my $node = { VALUE => $value };
               if ($list) {
                   $node->{LINK} = $list->{LINK};
                   $list->{LINK} = $node;
               } else {
                   $_[0] = $node;      # replace caller's version
               }
               return $node;
           }
       

      Но опять же , это все от лукавого .

      По-элементная работа с массивом ?

      Используем for/foreach:

          for (@lines) {
       		s/foo/bar/;	# change that word
       		tr/XZ/ZX/;	# swap those letters
           }
       

      Или:

          for (@volumes = @radii) {   # @volumes has changed parts
       		$_ **= 3;
       		$_ *= (4/3) * 3.14159;  # this will be constant folded
           }
       

      или :

      	@volumes = map {$_ ** 3 * (4/3) * 3.14159} @radii;
       

      Для хэша есть функция values :

          for $orbit ( values %orbits ) {
       		($orbit **= 3) *= (4/3) * 3.14159;
           }
       

      Манипуляция массива бит ?

      Используйте pack() , unpack(), vec() .

      Например:

          $vec = '';
           foreach(@ints) { vec($vec,$_,1) = 1 }
       

      Дан вектор $vec, получаем массив @ints :

          sub bitvec_to_list {
       	my $vec = shift;
       	my @ints;
       	# Find null-byte density then select best algorithm
       	if ($vec =~ tr/\0// / length $vec > 0.95) {
       	    use integer;
       	    my $i;
       	    # This method is faster with mostly null-bytes
       	    while($vec =~ /[^\0]/g ) {
       		$i = -9 + 8 * pos $vec;
       		push @ints, $i if vec($vec, ++$i, 1);
       		push @ints, $i if vec($vec, ++$i, 1);
       		push @ints, $i if vec($vec, ++$i, 1);
       		push @ints, $i if vec($vec, ++$i, 1);
       		push @ints, $i if vec($vec, ++$i, 1);
       		push @ints, $i if vec($vec, ++$i, 1);
       		push @ints, $i if vec($vec, ++$i, 1);
       		push @ints, $i if vec($vec, ++$i, 1);
       	    }
       	} else {
       	    # This method is a fast general algorithm
       	    use integer;
       	    my $bits = unpack "b*", $vec;
       	    push @ints, 0 if $bits =~ s/^(\d)// && $1;
       	    push @ints, pos $bits while($bits =~ /1/g);
       	}
       	return \@ints;
           }
       

      В цикле :

      	while($vec =~ /[^\0]+/g ) {
       	   push @ints, grep vec($vec, $_, 1), $-[0] * 8 .. $+[0] * 8;
       	}
       

      Используя модуль CPAN Bit::Vector:

          $vector = Bit::Vector->new($num_of_bits);
           $vector->Index_List_Store(@ints);
           @ints = $vector->Index_List_Read();
       

      Примеры с использованием vec():

          # vec demo
           $vector = "\xff\x0f\xef\xfe";
           print "Ilya's string \\xff\\x0f\\xef\\xfe represents the number ",
       	unpack("N", $vector), "\n";
           $is_set = vec($vector, 23, 1);
           print "Its 23rd bit is ", $is_set ? "set" : "clear", ".\n";
           pvec($vector);
       
           set_vec(1,1,1);
           set_vec(3,1,1);
           set_vec(23,1,1);
       
           set_vec(3,1,3);
           set_vec(3,2,3);
           set_vec(3,4,3);
           set_vec(3,4,7);
           set_vec(3,8,3);
           set_vec(3,8,7);
       
           set_vec(0,32,17);
           set_vec(1,32,17);
       
           sub set_vec {
       	my ($offset, $width, $value) = @_;
       	my $vector = '';
       	vec($vector, $offset, $width) = $value;
       	print "offset=$offset width=$width value=$value\n";
       	pvec($vector);
           }
       
           sub pvec {
       	my $vector = shift;
       	my $bits = unpack("b*", $vector);
       	my $i = 0;
       	my $BASE = 8;
       
       	print "vector length in bytes: ", length($vector), "\n";
       	@bytes = unpack("A8" x length($vector), $bits);
       	print "bits are: @bytes\n\n";
           }
       

      Data: Hashes (Associative Arrays)

      Работа с hash?

      Используем each() :

          while ( ($key, $value) = each %hash) {
       	print "$key = $value\n";
           }
       

      Для сортировки подходит foreach().

      Как найти элемент хэша по значению ?

      Создаем reverse hash:

          %by_value = reverse %by_key;
           $key = $by_value{$value};
       

      Более эффективно :

          while (($key, $value) = each %by_key) {
       	$by_value{$value} = $key;
           }
       

      Подсчитать размер хэша?

      Используем keys() :

          $num_keys = keys %hash;
       

      Отсортировать хэш по значению ?

          @keys = sort keys %hash;	# sorted by key
           @keys = sort {
       		    $hash{$a} cmp $hash{$b}
       	    } keys %hash; 	# and by value
       

      Или так :

          @keys = sort {
       		$hash{$b} <=> $hash{$a}
       			  ||
       		length($b) <=> length($a)
       			  ||
       		      $a cmp $b
           } keys %hash;
       

      Разница между "delete" и "undef" ?

      Если ключ $key присутствует в %hash, exists($hash{$key}) вернет true. Значение для этого ключа может быть undef, в этом случае $hash{$key} будет undef хотя exists $hash{$key} вернет true.

      Пример %hash :

      	  keys  values
       	+------+------+
       	|  a   |  3   |
       	|  x   |  7   |
       	|  d   |  0   |
       	|  e   |  2   |
       	+------+------+
       

      Далее

      	$hash{'a'}                       is true
       	$hash{'d'}                       is false
       	defined $hash{'d'}               is true
       	defined $hash{'a'}               is true
       	exists $hash{'a'}                is true (Perl5 only)
       	grep ($_ eq 'a', keys %hash)     is true
       

      Поэтому

      	undef $hash{'a'}
       

      теперь:

      	  keys  values
       	+------+------+
       	|  a   | undef|
       	|  x   |  7   |
       	|  d   |  0   |
       	|  e   |  2   |
       	+------+------+
       

      и далее :

      	$hash{'a'}                       is FALSE
       	$hash{'d'}                       is false
       	defined $hash{'d'}               is true
       	defined $hash{'a'}               is FALSE
       	exists $hash{'a'}                is true (Perl5 only)
       	grep ($_ eq 'a', keys %hash)     is true
       

      Теперь :

      	delete $hash{'a'}
       

      тогда :

      	  keys  values
       	+------+------+
       	|  x   |  7   |
       	|  d   |  0   |
       	|  e   |  2   |
       	+------+------+
       

      и далее :

      	$hash{'a'}                       is false
       	$hash{'d'}                       is false
       	defined $hash{'d'}               is true
       	defined $hash{'a'}               is false
       	exists $hash{'a'}                is FALSE (Perl5 only)
       	grep ($_ eq 'a', keys %hash)     is FALSE
       

      Уникальные ключи из 2-х хэшей ?

      Сначала извлекаем ключи из хэшей , затем удаляем дубликаты :

          %seen = ();
           for $element (keys(%foo), keys(%bar)) {
       	$seen{$element}++;
           }
           @uniq = keys %seen;
       

      Или :

          @uniq = keys %{{%foo,%bar}};
       

      Или :

          %seen = ();
           while (defined ($key = each %foo)) {
               $seen{$key}++;
           }
           while (defined ($key = each %bar)) {
               $seen{$key}++;
           }
           @uniq = keys %seen;
      
      Оставьте свой комментарий !

      Ваше имя:
      Комментарий:
      Оба поля являются обязательными

       Автор  Комментарий к данной статье