# LOGO 潳�滹�漶� 潳�滹手ˋ漶� 滹�滹�滹� 潳�滹手ㄓ滹手�漶� 滹罱▲�瓰��𥕞ㄨ漶撾�𥕞�漶潑�麨�𥕞�争�争�争�争ㄒ滹�滹�滹�滹�滹�滹�滹�滹�滹�滹�漶� 潳争朌滹胼�争�𥕞�圝朌漶猾╳漶仮稭滹手�鐥ˇ��麨�滹氯�𦥑�滹�漶氯�� 滹罱�� ��鐥�尠�争�争�争�争�争�争�争�争�争�争◣��� ��覀ㄖ �覔滹踱○漶���仮╪漶�稭���2漶� ��𦥑ˉ滹踱ˋ潳踱��糂滹嗯�謿�鐥�潳� 滹罱�砽ㄑ�𨸹�絍�絍�� 漶賤� 滹� ����轁ㄡ��嫰�𣏾�𥕞╪漶𢞖▼ 漶撾� 滹踱ˋ漶� 滹� 滹潑�罱�謿�漶撾ˋ��麨�滹罱﹞�𨸹�聦�絍��𥕞�𥕞�𥕞�𦥑▼ 潳�漶氯〃�覔��𨧀� ��鐥7漶�����𣏾𥼚滹�漶潑� 潳售ˋ漶麨4 潳�滹撾���鎿�𦥑�滹售ㄞ�聛�甅��尠�� 潳�滹氯�� 潳詹�� ��覀�仮稭�𨸹滹� �稭滹� ��争�𣏾5滹晦ˋ漶�滹�滹手聛滹麨ㄞ滹手ㄥ漶嗯Ⅶ滹踱ㄞ�� 潳�ˊ��滹�滹�滹罱ㄣ滹撾ㄞ�� 滹氯�� 潳�滹嫖ㄥ漶�潳�ㄦ滹嗯ㄓ滹潑ˋ漶踱�轁�𦥑ㄘ滹嗯�麨�𥕞ˋ滹踱ㄦ滹撾�𥕞�争�漶手聛��𥕞�圝�𦥑�争�𥕞ˋ漶踱�� 潳罱�� ��仮�𥕞ㄡ漶嗯ㄓ滹手ˋ漶踱�𦥑��朌�瓰��𥕞�𥕞�仮�𥕞�𥕞�𦥑�争覔�瓰�瓰潳踱ˋ滹謿�罱�砽�潳�滹罱𨸹潳�滹�ㄢ滹� 潳兩ㄥ滹色﹞滹�滹� ��争�滹氯�𦥑ㄧ��� 滹售ㄥ�聦��� ����𥕞朌潳踱ˋ滹踱�𥕞�𦥑�争�仮ˋ 滹罱▲滹徉ㄜ�絍滹凌� 潳�滹氯�麨�争╮漶謿□ 潳罱�� ��� 潳詹ˋ漶踱Ⅶ漶圝�圝糚�瓰�絍�絍�絍��麨�𦥑�滹�滹�滹���争稭滹� �糚滹踱甅��潳�滹撾甅�瓰�僙潳手ㄓ漶� 潳�滹�滹手ㄥ滹胼ㄔ滹手ㄓ漶嫰� ���ˉ滹踱ㄦ滹吲○�𨸹滹手�滹� ��� ��仮朌潳色��4漶� 潳�漶潑�𦥑ㄓ�聦��𦥑� 滹氯瓰�瓰潳嗯ㄥ滹踱ˋ��麨�𥕞Ⅲ滹踱ˋ��麨� ���朌滹踱�𨧀�𥕞甅滹色�漶��稭潳手� ��仮𡵆滹� 滹罱ˋ��麨�� 滹�滹�漶� 滹手ㄓ滹潑ˋ滹踱ㄦ滹�滹氯ˋ漶踱�� �糂漶� 潳領ˋ滹踱ㄥ滹�漶�朌滹� ����仮糚滹手�漶� ��爗╪滹𢞖�仮�� 潳售�麨� ��𥕞◣�絍��砽�𥕞�漶謿�争�仮瓰滹踱ˋ漶麨�� 滹� 滹踱ˋ滹把�仮8滹�漶�� ��争�争�仮8漶�����𥕞╪ 滹罱▼��𥕞7滹色ㄓ滹手ㄣ滹� ���▼��麨�𥕞�争�潳�滹�滹� ��争�仮�𥕞�圝� 漶� 滹賤ˋ��覀Ⅲ滹猾�����争�� �覔滹� �� 漶� 潳詹ˋ漶踱�争�仮�� ��� ����争�争� ��𣏾糚潳手�漶� 滹潑� 潳踱ˋ 滹踱���罱� ��罱�滹� 潳嫖� 滹猾� 漶� 滹���� 滹罱�嫰�滹�滹罱ㄓ滹手ㄦ滹𢞖�仮╪漶�潳�漶撾� 潳詹ˋ漶�滹領�� 潳嫖� 潳嫖�𢞖4滹鎿�� 潳領ㄖ滹罱ㄧ漶� 滹罱▽��麨�𥕞�争ㄔ漶撾Ⅶ滹踱ˋ滹踱� ��仮� 滹踱�謿ˋ漶踱� �朌滹猾═漶� 潳詹�� 潳踱�� ��争Ⅲ潳踱ˋ滹嗯ㄓ滹手�滹�滹�滹�滹手ㄣ漶踱�𦥑�滹罱●��麨�滹氯ˋ滹踱ˋ滹踱ˋ漶� 滹潑�麨ˉ滹踱ㄦ潳領�鎿� ��覀8漶� 滹罱ㄓ漶� ����𥕞� ��覀僙潳踱�𨧀�争�争�争�仮Ⅶ�匲潳領ˋ滹撾�嫰�𥕞� 滹撾�謿��Ⅲ滹踱ˋ滹踱ˋ漶�漶� 潳領ㄟ��麨���覀╪漶領ˋ漶� 潳詹ㄦ 滹踱�麨� ��仮�𦥑�𥕞稭滹嗯ㄥ�甅潳撾ˋ滹� 潳�滹� 潳領ˋ滹踱ˋ漶� 潳�滹氯�� �����4 滹詹�仮ㄕ潳售�� ��覀ˋ滹�潳潑ˋ滹踱���圝╰滹踱ˉ滹把� 潳手�滹踱ˋ滹踱“ 潳�滹撾� 潳�潳罱� 漶嫰�漶氯�滹詹�麨稭滹� �覔漶賤ˇ滹踱覔滹踱�滹撾0滹踱ˋ 漶� �朌滹踱ˋ滹踱� 潳罱ˋ潳� 漶� 漶� 潳�滹氯ˋ��潳�漶潑� ��� ����� 潳領ˋ滹把9潳麨絍潳撾�� 滹詹▼�� 潳罱ˇ漶麨Ⅳ 滹� 漶� 滹售�𦥑�仮� ���ˋ滹領ˇ滹色��9滹��滹嗯▼��滹�滹�滹撾Ⅶ漶�9 滹麨’滹把ㄥ��� unleashed �瓲潳踱�𨧀�𥕞朌�瓰�瓰�瓰��𦥑�罱▽潳𦥑ˇ滹謿ㄧ滹猾☆滹�1��麨�𥕞朌漶� v1.31 潳領� ��鐥�尠�𦥑�罱▽滹把ˋ����仮4滹賤�� ���稭潳色ㄓ滹手�滹手▲��� ���Ⅶ漶� 潳踱�� ��� ����� ��� # NAME e - beast mode unleashed # SYNOPSIS Add a trace marker: $ perl -Me -e 'sub f1 { trace } sub f2 { f1 } f2' Watch a reference for changes: $ perl -Me -e 'my $v = {}; sub f1 { watch( $v ) } sub f2 { f1; $v->{a} = 1 } f2' $ perl -Me -e ' package A { use e; my %h = ( aaa => 111 ); watch(\%h); sub f1 { $h{b} = 1; } sub f2 { f1(); delete $h{aaa}; } } A::f2(); ' Benchmark two snippets of code: $ perl -Me -e 'n { slow => sub{ ... }, fast => sub{ ... }}, 10000' Create a breakpoint in code: $ perl -Me -e 'repl' Invoke the Tiny::Prof: $ perl -Me -e 'prof' Convert a data structure to json: $ perl -Me -e 'say j { a => [ 1..3] }' Convert a data structure to yaml: $ perl -Me -e 'say yml { a => [ 1..3] }' Pretty print a data structure: $ perl -Me -e 'p { a => [ 1..3] }' Data dump a data structure: $ perl -Me -e 'd { a => [ 1..3] }' Devel::Peek dump a data structure: $ perl -Me -e 'dd { a => [ 1..3] }' Print data as a table: $ perl -Me -e 'table( [qw(key value)], [qw(red 111)], [qw(blue 222)] )' +------+-------+ | key | value | +------+-------+ | red | 111 | | blue | 222 | +------+-------+ Encode/decode UTF-8: $ perl -Me -e 'printf "%#X\n", ord for split //, enc "\x{5D0}"' 0XD7 0X90 $ perl -C -Me -e 'say dec "\xD7\x90"' $ perl -Me -e 'utf8; say dec "\xD7\x90"' �� And much, much more ... # DESCRIPTION This module imports many features that make one-liners and script debugging much faster. It has been optimized for performance to not import all features right away: thereby making its startup cost quite low. ## How to Import This module will overwrite existing methods of the same name (which triggers a warning)! Should this happen and it is not desired, simply import this module first. Should you prefer the methods in this module, import this module last (if needed, at the end of the file). # SUBROUTINES ## Investigation ### repl Add a breakpoint using [Runtime::Debugger](https://metacpan.org/pod/Runtime%3A%3ADebugger). Basically inserts a Read Evaluate Print Loop. Version 0 was basically: while ( 1 ) { my $input = <STDIN>; last if $input eq 'q'; eval "$input"; } (Much more powerful since then). Enable to analyze code in the process. CODE ... # Breakpoint use e; repl CODE ... Simple debugger on the command line: $ perl -Me -e 'repl' ### trace Show a stack trace. trace( OPTIONS ) OPTIONS: -levels => NUM, # How many scope levels to show. NUM, # Same. -raw => 1, # Include internal calls. -NUM, # Same. -message => STR, # Message to display. STR, # Same. ### watch Watch a reference for changes. watch( $ref, OPTIONS ) OPTIONS: -clone => 0, # Will not watch cloned objects. -methods => "fetch", # Monitor just this method. -methods => [ "fetch" ], # Same. -levels => NUM, # How many scope levels to show. NUM, # Same. -raw => 1, # Include internal calls. -NUM, # Same. -message => STR, # Message to display. STR, # Same. ### prof Profile the code from this point on. my $obj = prof; ... # $obj goes out of scope and builds results. ### n Benchmark and compare different pieces of code. Time single block of code. n sub{ ... }; n sub{ ... }, 100000; # Compare blocks of code. n { slow => sub{ ... }, fast => sub{ ... }, }; n { slow => sub{ ... }, fast => sub{ ... }, }, 10000; $ perl -Me -e '$v = 333; n { concat => sub { 111 . $v }, interp => sub { "111$v" }, list => sub { 111,$v } }, 100000000' Rate interp concat list interp 55248619/s -- -6% -62% concat 58479532/s 6% -- -60% list 144927536/s 162% 148% -- ## Format Conversions ### j JSON Parser. my $bytes = j([1, 2, 3]); my $bytes = j({foo => 'bar'}); my $value = j($bytes); Encode Perl data structure or decode JSON with ["j" in Mojo::JSON](https://metacpan.org/pod/Mojo%3A%3AJSON#j). Convert Perl object to JSON string: $ perl -Me -e 'say j { a => [1..3]}' Convert JSON string to Perl object: $ perl -Me -e 'p j q({"a":[1,2,3]})' ### x XML parser. my $dom = x('<div>Hello!</div>'); Turn HTML/XML input into [Mojo::DOM](https://metacpan.org/pod/Mojo%3A%3ADOM) object. $ perl -Me -e 'say x("<div>hey</dev>")->at("div")->text' Force HTML semantics: $ perl -Me -e 'say x->xml(0)->parse("<Tag>Name</Tag>")' <tag>Name</tag> Force XML semantics (case sensitive tags and more): $ perl -Me -e 'say x->xml(1)->parse("<Tag>Name</Tag>")' <Tag>Name</Tag> ### yml YAML parser. Convert Perl object to YAML string: $ perl -Me -e 'say yml { a => [1..3]}' Convert YAML string to Perl object: $ perl -Me -e 'p yml "---\na:\n- 1\n- 2\n- 3"' ### clone Storable's deep clone. $ perl -Me -e ' my $arr1 = [ 1..3 ]; my $arr2 = clone $arr1; $arr2->[0] = 111; say $arr1; p $arr1; say ""; say $arr2; p $arr2; ' # Output: ARRAY(0x5d0b8a408518) [ [0] 1, [1] 2, [2] 3, ] ARRAY(0x5d0b8a42d9e0) [ [0] 111, [1] 2, [2] 3, ] ### enc Encode UTF-8 code point to a byte stream: $ perl -Me -e 'printf "%#X\n", ord for split //, enc "\x{5D0}"' 0XD7 0X90 ### dec Decode a byte steam to UTF-8 code point: $ perl -C -Me -e 'say dec "\xD7\x90"' �� ### utf8 Set STDOUT and STDERR as UTF-8 encoded. If given a filehandle, will set the encoding for it to UTF-8. utf8($fh); ## Enhanced Types ### b Work with strings. my $stream = b('lalala'); Turn string into a [Mojo::ByteStream](https://metacpan.org/pod/Mojo%3A%3AByteStream) object. $ perl -Me -e 'b(g("mojolicious.org")->body)->html_unescape->say' ### c Work with arrays. my $collection = c(1, 2, 3); Turn list into a [Mojo::Collection](https://metacpan.org/pod/Mojo%3A%3ACollection) object. ### set Work with sets. my $set = set(2,4,6,4); Turn list into a [Set::Scalar](https://metacpan.org/pod/Set%3A%3AScalar) object. $ perl -Me -e 'say set(2,4,6,2)' (2 4 6) Get elements: $ perl -Me -e 'say for sort(set(2,4,6,2)->elements)' $ perl -Me -e 'say for sort(set(2,4,6,2)->@*)' 2 4 6 Check for existence of an element: $ perl -Me -e 'say set(2,4,6,2)->has(7)' $ perl -Me -e 'say set(2,4,6,2)->has(4)' 1 Intersection: $ perl -Me -e 'say set(2,4,6,2) * set(3,4,5,6)' (4 6) Create a new universe: # Universe 1: # ... Set::Scalar::Universe->new->enter; # Universe 2: # ... Operations: set value $a (a b c d e _ _ _ _) $b (_ _ c d e f g _ _) $c (_ _ _ _ e f g h i) union: $a + $b (a b c d e f g _ _) union: $a + $b + $c (a b c d e f g h i) intersection: $a * $b (_ _ c d e _ _ _ _) intersection: $a * $b * $c (_ _ _ _ e _ _ _ _) difference: $a - $b (a b _ _ _ _ _ _ _) difference: $a - $b - $c (a b _ _ _ _ _ _ _) unique: $a % $b (a b _ _ _ f g _ _) symm_diff: $a / $b (a b _ _ _ f g _ _) complement: -$a (_ _ c d e f g h i) ## Files Convenience ### f Work with files. my $path = f('/home/sri/foo.txt'); Turn string into a [Mojo::File](https://metacpan.org/pod/Mojo%3A%3AFile) object. $ perl -Me -e 'say r j f("hello.json")->slurp' ## Math Help ### max Get the biggest number in a list. $ perl -Me -e 'say max 2,4,1,3' 4 ### min Get the smallest number in a list. $ perl -Me -e 'say max 2,4,1,3' 1 ## Output ### say Obnoxious print with a newline. $ perl -Me -e 'say 123' $ perl -Me -e 'say for 1..3' Always sends output to the terminal even when STDOUT and/or STDERR are redirected: $ perl -Me -e ' say "Shown before"; close *STDOUT; close *STDERR; say "Shown with no stdout/err"; print "Print not seen\n"; ' 111 222 ### p Pretty data printer. $ perl -Me -e 'p [1..3]' ### np Return pretty printer data. $ perl -Me -e 'my $v = np [1..3]; say "got: $v"' Can be used with `say` to output to the terminal (incase STDOUT/STDERR are redirected): $ perl -Me -e ' close *STDOUT; close *STDERR; say np [ 1.. 3 ]; ' ### d Data dumper. $ perl -Me -e 'd [1..3]' ### dd Internal data dumper. $ perl -Me -e 'dd [1..3]' ### dye Color a string. $ perl -Me -e 'say dye 123, "RED"' ### table Print data as a table: $ perl -Me -e 'table( [qw(key value)], [qw(red 111)], [qw(blue 222)] )' +------+-------+ | key | value | +------+-------+ | red | 111 | | blue | 222 | +------+-------+ Context sensitive! - Void - output table. - List - return individual lines. - Scalar - return entire table as a string. ## Web Related ### g my $res = g('example.com'); my $res = g('http://example.com' => {Accept => '*/*'} => 'Hi!'); my $res = g('http://example.com' => {Accept => '*/*'} => form => {a => 'b'}); my $res = g('http://example.com' => {Accept => '*/*'} => json => {a => 'b'}); Perform `GET` request with ["get" in Mojo::UserAgent](https://metacpan.org/pod/Mojo%3A%3AUserAgent#get) and return resulting [Mojo::Message::Response](https://metacpan.org/pod/Mojo%3A%3AMessage%3A%3AResponse) object. $ perl -Me -e 'say g("mojolicious.org")->dom("h1")->map("text")->join("\n")' ### post my $res = post('example.com'); my $res = post('http://example.com' => {Accept => '*/*'} => 'Hi!'); my $res = post('http://example.com' => {Accept => '*/*'} => form => {a => 'b'}); my $res = post('http://example.com' => {Accept => '*/*'} => json => {a => 'b'}); Perform `POST` request with ["get" in Mojo::UserAgent](https://metacpan.org/pod/Mojo%3A%3AUserAgent#get) and return resulting [Mojo::Message::Response](https://metacpan.org/pod/Mojo%3A%3AMessage%3A%3AResponse) object. $ perl -Me -e 'say post("mojolicious.org")->dom("h1")->map("text")->join("\n")' ### l Work with URLs. my $url = l('https://mojolicious.org'); Turn a string into a [Mojo::URL](https://metacpan.org/pod/Mojo%3A%3AURL) object. $ perl -Me -e 'say l("/perldoc")->to_abs(l("https://mojolicious.org"))' ## Asynchronous This sector includes commands to run asynchronous (or pseudo-async) operations. It is not entirely clear which method to always use. `runf` limits to number of action or 20 (whichever is smaller). `runt` and `runio` have no such limits. Typically using threads (with `runt`) seems to be fastest. Some statistics using different run commands: $ gitb status -d s/iter runt runio runf series runt 1.74 -- -35% -59% -74% runio 1.12 55% -- -36% -59% runf 0.716 142% 56% -- -36% series 0.456 281% 146% 57% -- $ gitb branch -d Rate runt runf series runio runt 0.592/s -- -71% -81% -83% runf 2.02/s 240% -- -34% -42% series 3.05/s 415% 51% -- -12% runio 3.47/s 486% 72% 14% -- $ gitb pull -d s/iter runio series runt runf runio 4.27 -- -7% -21% -33% series 3.97 8% -- -15% -28% runt 3.38 26% 17% -- -15% runf 2.87 49% 38% 18% -- ### runf Run tasks in parallel using [Parallel::ForkManager](https://metacpan.org/pod/Parallel%3A%3AForkManager). Returns the results. $ perl -Me -e ' p { runf map { my $n = $_; sub{ $n => $n**2 }; } 1..5 } ' { 1 => 1, 2 => 4, 3 => 9, 4 => 16, 5 => 25, } Takes much overhead to start up! Will use up to 20 processes. ### runio Run tasks in parallel using [Mojo::IOLoop](https://metacpan.org/pod/Mojo%3A%3AIOLoop). Returns the results. $ perl -Me -e ' p { runio map { my $n = $_; sub{ $n => $n**2 }; } 1..5 } ' { 1 => 1, 2 => 4, 3 => 9, 4 => 16, 5 => 25, } This is apparently better to use for IO related tasks. ### runt Run tasks in parallel using [threads](https://metacpan.org/pod/threads). Returns the results. $ perl -Me -e ' p { runt map { my $n = $_; sub{ $n => $n**2 }; } 1..5 } ' { 1 => 1, 2 => 4, 3 => 9, 4 => 16, 5 => 25, } This is the fastest run\* command usually. ## Package Tools ### monkey\_patch Insert subroutines into the symbol table. Extracted from Mojo::Util for performance. Imports method(s) into another package (as done in this module): Take a look at the import method for an example. ### pod Work with perl pod. ### import Imports a DSL into another package. Can be used in a sub class to import this class plus its own commands like this: package e2; use parent qw( e ); sub import { shift->SUPER::import( scalar caller, my_command_1 => sub {}, my_command_2 => sub {}, my_command_3 => sub {}, ); } # AUTHOR Tim Potapov, `<tim.potapov[AT]gmail.com>` # BUGS Please report any bugs or feature requests to [https://github.com/poti1/e/issues](https://github.com/poti1/e/issues). # SUPPORT You can find documentation for this module with the perldoc command. perldoc e You can also look for information at: [https://metacpan.org/pod/e](https://metacpan.org/pod/e) [https://github.com/poti1/e](https://github.com/poti1/e) Logo was generated using: [https://emojicombos.com/dot-art-editor](https://emojicombos.com/dot-art-editor) # LICENSE AND COPYRIGHT This software is Copyright (c) 2024 by Tim Potapov. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible)