# LOGO ⢀⣀⡤ ⢀⣤⣿⡗ ⣀⣀⣀ ⢀⣤⣤⣤⣄⡀ ⣠⡶⠿⠛⣹⡾⠛⢁⡼⠟⢛⠉⠉⠉⣉⣣⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⡄ ⢉⠻⣯⣉⡛⠒⠻⡷⢮⡙⠳⣤⡐⣾⠟⣀⣴⠋⠁⣀⡴⠋ ⣠⡟ ⠐⠚⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⢩⠛ ⠘⣧ ⠹⣿⡳⡀⠙⢦⡈⠳⠈⢱⡟ ⠋⣼⣿⣿⢿⠁⠰⣶⠏⢐⡆⢠ ⣠⣖⣢⠤⠶⠶⠂ ⡽⢃ ⣀ ⠈⢗⣲⠞⠓⠛⢦⡌⡿ ⡾⠃ ⣿⣿⡾ ⣿ ⣼⣠⠏⢀⡾⣿⠟⣂⣠⡤⠤⠴⠶⠛⠛⠛⢋⡿ ⢀⡴⡲⠹⠍⠁ ⠐⢶⡂⠈⣓⠱⣆⡼⠃ ⢰⣿⡟⢳ ⢀⣾⢇⡜⠋⠁⣰⣯⠾⠷⠚⠉ ⢀⣴⠎ ⢸⡇ ⠘⠙⠳⠤⣕ ⠳⣄ ⠉⠓⢴⣱⣿⡅⣀⣤⠾⣟⣯⣤⣶⡶⢿⣿⣯⠆ ⢈⣽⠃⣀⣀⣠⣴⣾⣯⠄ ⣴⠇ ⢀⣹⣶⡀⢈⣷⣶⣤⣼⣿⡿⢗⡋⣩⣶⡟⣛⣿⣿⣷⣾⣛⣉⣀⡤⠾⠛⠒⠋⠉⠛⣿⡿⠋ ⢠⡏ ⠙⠛⣲⡶⣤⣤⣿⡿⠋⠁⠻⠿⠛⠛⠙⠛⠛⠋⠉⠹⠿⠿⢿⣿⣏⣠⡖⣀⢀⣠⠤⢀⣈⣳⣄ ⢨⣶⣦⡤⣄⣀ ⠉⢁⣴⣋⣸⠟ ⣰⣶⠴⠒ ⠈⠛⠻⢿⣿⣿⡛⠋⠉⠙⣿ ⣠⡶⣫⣭⠶⣭⡀ ⢀⣴⠟⠉⢡⡏⡼ ⢠⡞ ⠉ ⢸⣿⡿⢿⡒⠒⠲⠿⠶⠶⠶⠟⠋⠁⣀⣀⣀⠉⠳⣄ ⠲⣿⠷⠃⢀⣾⠷⠿⠦⢤⣤⡟ ⢀⣀⣤⣶⣯⣥⣤⣤⡞⠁ ⠈⣼⣿⣷⣝⡳⠤⣤⣀⣀ ⠉ ⠙⠻⢦⣈⢳⡄ ⢀⡼⢋⣤⠴⠋⠁ ⣴⠿⠿⢶⣶⣿⣿⠟⠛⢻⣿⣿⠟⠁ ⠈⠻⣿⡍⠛⠷⣦⣄⡀⠳⢤⡀ ⠙⠧⣄ ⣠⣿⠟⠉ ⣀⣀⡀ ⣤⣤⣼⣿⣿⣷⣂⣴⣿⡿⠋ ⠰⡆ ⢻⣿⣿⣶⣄⡈⠻⣝ ⠈⠙⠲⣤⣀⡀ ⠑⢦⣌⡙⠒ ⢰⡟⠁ ⠛⢩⠶⠖⠛⣀⡏⠉⠙⠿⣿⣿⡟⠉ ⣷ ⣿⣿⣧⡙⢷⣄⡈⠂ ⠉⠉⠙⢷⡄⠈⠛⢦ ⣠⡿⠛⢶⣦⣤⣤⣴⣶ ⠈⡿⠟⠛⠉⠁⢀⣀⣀ ⠉⠙⠛⠒⠂ ⡿ ⣽⣿⠘⢻⣷⡀⠈⠉⠉ ⠹⣆ ⠁ ⡏ ⢸⣿⡿⠉⠙⠋ ⠈ ⠈⠉⣉⠅ ⠓⠲⢤⣄⡀ ⣼⠃ ⢿⣿ ⣿⠇⢠⡀ ⠠⣄⣄ ⢹⡆ ⣷⡀ ⡿ ⣀⠔ ⣠⣞⣁⣀⣠⣤⣤⣷⣌⠙⢦⡀⢀⡾⠃ ⢸⣿⡆⣻⠇ ⢹⣄ ⢹⡌⢳⣜⡟ ⢻⣧⣠⣸⡇ ⣠⡾⠟⠛⠉⣥⡾⢿⣿⣿⣿⣆ ⠙⠃ ⣿⢏⣿⡿⡀ ⠻⣷⢤⡀ ⢸⡇ ⢿⡇ ⠉⢻⢿⣿⣶⣤⣤⣀⣀⣀⣀⣤⣴⡿⠋⠁⣠⡴⠟⢁⣴⣿⣿⣿⣿⣿⡆ ⣼⡟⣼⣿⣷⢻⡜⣆ ⠘⢷⡙ ⣠⣤⡿ ⠈⠛⠁ ⠘⠦⢿⣍⠉⠉⠉⠙⢿⠩⢻⣿⣾⠞⠛⠁ ⣾⠏⠈⢻⣿⣿⣿⣿⡀⡀ ⢻⣰⠟⠁⠘⢦⡻⣿⡆ ⢸⣷ ⣿⡟⠁ ⠙⠋⠛⠳⣶⣶⠷⢾⣿⣿ ⢀⣿ ⢻⣿⣿⣿⡧ ⢀⣴⠋ ⠁⠈⢳ ⣸⠙⣦⢰⡟ ⠘⣿⣄⢼⣿⣿⣇⠒⢢⣿⣼⣧⡀ ⢤⡀⣿⣿⣿⡧ ⢀⣾⠃ ⢀⢠⡆ ⡞⢀⡴⣃⣸⡟⠳⣇ ⠹⡽⣾⣿⠹⣿⣆⣾⢯⣿⣿ ⡞ ⠻⣿⣿⣿⠁ ⢠⣿⢏ ⡀ ⡟ ⢀⣴⣿⠃⢁⡼⠁ ⠈ ⠈⠛ ⢻⣿⣧⢸⢟⠶⢾⡇ ⣸⡿⠁ ⢠⣾⡟⢼ ⣷ ⡇ ⣰⠋⠙⠁ ⠈⣿⣻⣾⣦⣇⢸⣇⣀⣶⡿⠁⣀⣀⣾⢿⡇⢸ ⣟⡦⣧⣶⠏ unleashed ⠸⢿⡍⠛⠻⠿⠿⠿⠋⣠⡾⢋⣾⣏⣸⣷⡸⣇⢰⠟⠛⠻⡄ v1.27 ⢻⡄ ⠐⠚⠋⣠⡾⣧⣿⠁⠙⢳⣽⡟ ⠈⠳⢦⣤⣤⣀⣤⡶⠛ ⠈⢿⡆ ⢿⡇ ⠈ ⠈⠓ ⠈ # 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' Launch the Runtime::Debugger: $ 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"' א # 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. # SUBROUTINES ## Investigation ### repl Add a breakpoint to code. Basically inserts a Read Evaluate Print Loop. Enable to analyze code in the process. CODE ... # Breakpoint repl CODE ... Simple debugger on the command line: $ perl -Me -e 'repl' ### trace Show a stack trace. trace( $depth=1 ) ### 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; ## 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('
Hello!
'); Turn HTML/XML input into [Mojo::DOM](https://metacpan.org/pod/Mojo%3A%3ADOM) object. $ perl -Me -e 'say x("
hey")->at("div")->text' Force HTML semantics: $ perl -Me -e 'say x->xml(0)->parse("Name")' Name Force XML semantics (case sensitive tags and more): $ perl -Me -e 'say x->xml(1)->parse("Name")' Name ### 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' ## 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 exturely clear with method to always use. Typically using threads (with `runt`) is the 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! ### 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. Import methods into another package (as done in this module): $ perl -e ' package A; use e; sub import { my $c = caller(); monkey_patch $c, new => sub { say "Im new" }; } package main; A->import; new(); ' Im new Import methods into the same package (probably not so useful): $ perl -e ' package A; use e; sub import { my $c = caller(); monkey_patch $c, new => sub { say "Im new" }; } A->import; A->new(); ' Im new Perhaps can be updated based on the outcome of this issue: [https://github.com/mojolicious/mojo/pull/2173](https://github.com/mojolicious/mojo/pull/2173) ### pod Work with perl pod. ### import \[Internal\] Imports the 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 { my ( $class ) = @_; my $class = caller; $class->SUPER::import( $caller ); $class->can("monkey_patch")->( $caller, my_command_1 => sub {}, my_command_2 => sub {}, my_command_3 => sub {}, ); } # AUTHOR Tim Potapov, `` # 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)