By default, Raku's "die" reports the line number where the "die" is located, what if you'd like the line number of the calling context, ala "carp" with perl 5?
There is no direct equivalent to carp, but you can start raku with the --ll-exception parameter, which will create a full stack trace on an execution error.
I guess nobody has gotten around to creating a Carp module yet. Creating a carp sub shouldn't be too difficult, given that there is a Backtrace class:
$ raku -e 'say "file: {.file}:{.line}" for Backtrace.new'
file: SETTING::src/core.c/Backtrace.pm6:94
file: SETTING::src/core.c/Backtrace.pm6:94
file: -e:1
There is now a Carp module available on GitHub and should soon be available in the Raku ecosystem. It currently only supports the most basic functionality, but over time it should be improved.
So the answer to your question is to use Carp like you would in Perl 5. :-)
Related
What's the difference between the Perl JSON modules below?
I have come across JSON::PP and JSON::XS. The documentation of JSON::PP says it is compatible with JSON::XS. What does that mean?
I am not sure what the difference between them are, let alone which of them to use. Can someone clarify?
Perl modules sometimes have different implementations. The ::PP suffix is for the Pure Perl implementation (i.e. for portability), the ::XS suffix is for the C-based implementation (i.e. for speed), and JSON is just the top-level module itself (i.e. the one you actually use).
As noted by #Quentin, this site has a good description of them. To quote:
JSON
JSON.pm is a wrapper around JSON::PP and JSON::XS - it also does a bunch of moderately crazy things for compatibility reasons, including extra shim code for very old perls [...]
JSON::PP
This is the standard pure perl implementation, and if you're not performance dependent, there's nothing wrong with using it directly [...]
JSON::XS
Ridiculously fast JSON implementation in C. Absolutely wonderful [...]
As you can see, just installing the top-level JSON module should do it for you. The part about compatibility just means that they both do the same thing, i.e. you should get the same output from both.
I installed the Perl JSON module a few years ago on a RHEL server I managed and it was a really straightforward process: just install (or build) the module from the CPAN site and you're done.
Installing should be a simple case of either using the OS package manager (if in GNU/Linux), using the cpan utility, or building from source. The OS package manager is recommended, as it helps keep things updated automatically.
To verify that it's installed, just try the following command from the terminal (assuming GNU/Linux):
$ perl -e 'use JSON;'
If it doesn't complain, then you should be good to go. If you get errors, then you should get ready to go in an adventure.
You can install JSON module, cpan install JSON
use JSON;
my $result = from_json($json);
if($result->{field})
{
# YOUR CODE
};
This question already has answers here:
Executing system commands safely while coding in Perl
(3 answers)
Closed 6 years ago.
Like executing a command using backticks or exec() or system().
Yes, this is bad practice in almost all cases! This is especially true if you have a choice.
Executing external commands is:
Very hard to do correctly (but very easy to get sort-of-working). You can't just escape the shell args and call it a day, you have to account for potentially multiple levels of escaping for potentially different languages.
Slow. A fork+exec to e.g. rm is easily a thousand times slower than the corresponding syscall.
A rigid, error-prone and inexpressive integration point. You typically have to convert data to flat lists of strings and back. You can't use the language's features like exception handling, nested data structures or callbacks.
Due to this, the following are BAD reasons to call external commands:
Not knowing how to do X in your language, but knowing a shell command for it. A typical example is cp -R foo bar.
Not knowing how something works, but knowing a shell oneliner that does it. A typical example is foo *.mp4 > >(tee file).
Not wanting to learn a new API for e.g. json or http, and instead using shell tools like jq or curl.
However, if you are calling a program that does non-trivial things, that doesn't have a native library or bindings, AND that you know how to invoke with execve semantics (NOT system nor perl exec semantics that invoke shells), this is a valuable tool.
Examples of good uses of executing external commands that follow all the above is invoking make to build a project from an installer, or running java -jar ... to start a Minecraft server.
It's a great* practice. Perl and PHP are great for lots of things, but they're not great at everything, and there's a use case for using external programs and other tools in your project. But one of things that Perl is definitely great at is gluing together input and output formats and letting you mash together several different tools into a single project, letting each part of the project do what they do best.
* by which I mean, often a great practice. Things like #files=qx(ls $dir) and #txt=qx(cat $textfile) make all right-thinking Perl programmers cringe.
Some operating system commands might have built-in functionality not available in language (Perl's mkdir() lacks *ix mkdir's -p). Then again, something might be easier to do using languages constructs instead of parsing output (readdir() vs ls).
And it is important to remember that something written in Perl might be more portable to non-Unix systems than calling OS-specific external programs.
Why not?
But, be careful and escape all strings inserted in the command:
In PHP: escapeshellarg()
In Perl: Perl equivalent of PHP's escapeshellarg
I've installed the Yojson library for OCaml via GODI:
http://martin.jambon.free.fr/yojson.html
I want to start an interactive ocaml session (i.e. via the ocaml command) and execute functions from the Yojson library e.g.
Yojson.Safe.from_string;;
How do I do this? The above command gives "Error: Unbound module Yojson". I've worked out how to compile via ocamlc with Yojson available, but I want to launch an interactive session instead.
I know this seems like a horrible beginners question but Yojson comes with no samples and minimal instructions so I'm really stumped. I've tried various combinations of "#load" and compiler switches and I'm stuck.
The tool you are after is called findlib. It is included in the base GODI installation. The tools that come with findlib allow you to easily compile against most OCaml libraries and use those libraries from a toplevel session (ocaml). The findlib documentation is fairly comprehensive, but here is a quick summary to get started.
To start using findlib from within a toplevel session:
#use "topfind";;
This will display a brief usage message. Then you can type:
#list;;
This will show you a list of all of the available packages. Yojson will likely be among them. Finally:
#require "yojson";;
where yojson is replaced by the appropriate entry shown by #list;;. Yojson's modules should be available for you to use at this point.
I'm using ripper to doing ruby-code lexing in mri-1.9.*, I would like to do the same thing in JRuby, I noticed there is this org.jruby.lexer.yacc.RubyYaccLexer used in org.jruby.parser.DefaultRubyParser, I'm thinking that I can use it to do what ripper in mri-1.9.* does, though definitely at a lower level as compared to ripper. Being a noob in java, I couldn't figure out how to use it from within jruby. I'm not sure if it is doable at all, hope to get some advice on this.
Take a look at this post from JRuby committer Ola Bini. In it he shows some brief usage of JRuby's AST. You can use the code from JRuby to create an AST and navigate it in memory, manipulate it, and turn it back into executable code.
require 'jruby'
JRuby.ast_for "puts 'hello'"
# => RootNode
# NewlineNode
# FCallOneArgNode |puts|
# ArrayNode
# StrNode =="hello"
It doesn't give you the same event-like approach like Ripper does, but by traversing the AST you can get similar information.
Are there any software packages or projects that provide the scripting language shells? I know there's csh for C programmers although not in a sense that it's primarily for programming, but for navigation and system administration. I was wondering if there is something inverted for this purpose? I.e. user logs into a shell that's primarily for programming and then for navigation (something like irb in ruby, but with navigation capabilities)?
I think you're misinformed if you think csh (tcsh) is for C programmers. It's just a shell like bash or ash or dash or ksh or zsh.
The R language provides a reasonably functional internal environment, complete with the ability to save/restore the "workspace" (your variables).
Python has a built-in interpreter, as does Maxima, and some Lisp/Scheme versions, plus you already mentioned irb.
You could also view vim or emacs as the type of programmer-centric shell you're talking about; both can be hooked up to run navigation commands and sysadmin-type stuff without forcing you to leave the editor.
I think the real answer to your question is "powerful shells provide their own scripting language".
Tcl's interpreter, tclsh, is really designed to be a shell. In fact, unlike Ruby where the interactive and non interactive shell are separate, tclsh works just like traditional shells like bash: if run without a script it enters interactive mode but given a script it enters batch mode.
But, it does suck in that it doesn't have readline built-in. So no up-arrow history or tab completion etc. But you can always run it using rlwrap:
rlwrap tclsh
which should give you readline capabilities.
However, I wasn't satisfied (partly because my system at the time didn't have rlwrap and partly because there were a few more features I wanted). So I wrote my own implementation of history and tab completion etc. Checkout my original Pure-tcl readline or the improved Pure-tcl readline2.
It really does act like an interactive shell complete with auto-executing external executables if a tcl command is unknown. And you can even execute interactive programs like vi, emacs or lynx from it. Because it automatically falls back to executing external commands, you can mix tcl and shell like:
foreach x [split [ps aux | grep apache] \n] {
puts [lindex $x 1]
}
This is great because tcl's syntax is much saner compared to bash and sh (ever tried to get out of '"\"\\\\"\ quoting hell in bash?). I personally like tcl but tcl is kind of a love-it-or-hate-it language. People who get it really love it and people who don't really hate it.
But even if you don't quite like tcl syntax I'd suggest you give it a try for this specific application because unlike other languages tcl really is designed to be used more as a command language than a programming language. Read I can’t believe I’m praising Tcl for some of the reasons why.
System navigation (and administrative tasks) are a really different application than programming, and it's hard to find a single shell that does both well. However, I'm guessing that what you're really asking for is a shell that
Lets you easily load the contents of a file and manipulate those contents in-process and with more dexterity than you get using bash and standard unix utilities.
In addition you want the convenience of accessing some of the normal commands for moving files around and navigating the file system.
The good news is that the standard scripting languages (e.g. Ruby, Perl) were meant to do #1 really well, and it's not hard to write/find a library to do #2 any of these langauges.
Because Ruby is what I'm familiar with, I'm going to give you a more concrete example of how you might accomplish this using Ruby.
To do this in Ruby, you would use irb (the Ruby REPL), and the FileUtils module which is part of Ruby's standard library.
To do this, start irb, then run
require 'fileutils'
include FileUtils
(you can put this in .irbrc if you'd like, but I'm not sure I'd recommend that.)
this allows you to have access to a number of the normal file manipulation commands through easy Ruby syntax. You can run other Ruby commands automatically yourself. To run other commands on your system, you're going to have to call them with system.
FileUtils doesn't include an ls command, because it wasn't really meant to be used interactively, so you'll need to write your own. I don't know a way to get good job control at all (that's not to say you couldn't write something though).
The only thing I warn you is that this workflow will be very different than other UNIX users, so you might want to think about being such a nonconformist is worth it, or whether you'd rather build experience that meshes well with other UNIX admins' working styles. It's probably better to get used to the core UNIX utils and the Bourne shell scripting language. (You could learn C-Shell if you want, but there is a well-known FAQ explaining the disadvantages of the C-shell for programming.)
You may want to take a look at IPython. It is an interactive Python shell (with filesystem navigation alongside other nice features) and it also provides a system shell profile to optimize its behavior for system shell usage.
CSH has nothing to do with C programming. It's serves the same functions as the Bourne Shell about equally well, but uses different syntax.
If you want C interpreter, I suggest using cint, which is part of CERN's ROOT system. But keep in mind that it's not useful in the least for system administration and navigation.
I'm sure with a little bit of work you could further extend Devel::REPL (Perl) to provide access to gnu coreutils,
Bash has lots of programming features that aren't ordinarily acknowledged, for example arrays and string manipulation options when expanding a shell variable. Some shells, like zsh or ksh have greatly improved programming features compared to the most common shells (namely bash or tcsh.)