I'm a user of the Ruby language, and while the idea of using the Crystal language as a one-liner may be silly, the Crystal language is so fast that even when you add up the compile time, it can sometimes run faster than writing one-liners in Ruby. Is there a way to do one-liners in Crystal?
It can, but its definitely not written with that in mind like Perl and to some degree Ruby.
This is mostly down to Crystal intentionally not inheriting many of the Perlisms that makes this so convenient in Ruby, such as the -p, -n etc command line flags and globals like $_, $' etc.
Other than that, nothing stops you from running crystal eval 'some code' to your heart's content.
Yes, it definitely is not only possible but very easy. I have never used Crystal before in my life, and I was able to create a one-liner in less than 5 seconds:
puts "Hello, World!"
Related
Whenever I set out to learn a language the first thing I do is produce an executable file written in that language (it could be a compiled program or a script) that when run prints 'hello, world' and a newline to stdout:
theironknuckle#beastbook:~/Code$ ./hello
hello, world
After about an hour of mucking around with GNU Smalltalk, I haven't found out how to do this.
(I know that the hello world program can be expressed from within a session as
'hello, world' printNl
This doesn't meet my stdout requirements)
I understand that there's no mainline in Smalltalk. So I'm quite intrigued by what sort of boilerplate could possibly be necessary to make it happen. Again, the file doesn't necessarily have to be compiled, but the end result of the exercise has to be smalltalk code that results in the above session extract.
PS. yesyesyes I know that I'm doing it wrong by not embracing the "image based programming" philosophy. I don't care. I'm not against learning how to work with the image and IDE and all that, but I really have minimal interest right now. What I care about is the Smalltalk language itself. Syntactically, philosophically and typographically it is rather beautiful. I feel comfortable learning programming languages from a commandline interpreter and a text editor. :)
In GNU Smalltalk, there's pretty much no boilerplate.
You could just put your single line in a .st file, and run it with gst hello.st
If you want to explore using a class instead of directly executed statements, then that's easy too, the following in a file passed to gst will do the trick:
Object subclass: Hello [
greet [
'Hello, World' displayNl
]
].
greeting := Hello new.
greeting greet.
Files passed to gst on the command line are parsed and executed in sequence, so you could split the above listing into two separate files - one to declare / compile the class, and the second to actually run it.
Once you've developed your program, you can use the -S flag to gst to snapshot the image after loading your classes, so that you don't have the compilation overhead each time, and can just run your startup statement instead.
gst also has shebang support, so you can put #! /usr/bin/gst -f at the top of your file if you don't want to pass it to gst manually. (See the documentation on invocation for more, including how to do it without hardcoding the location of gst)
I want to learn Sed. Can you please point me to good references so that I can fully utilize it.
I want to learn it to perform more of the do-once-then-forget type administrative or dev-tools like tasks. So, I don't really care about performance or modularity or object orientedness etc when writing this type of code. Do you think it would be a good idea to learn Sed? Or should I learn Ruby? My main concern is the conciseness of scripts, but not to the point of making it totally obscure looking piece of code.
Thanks
Ajay
I can't think of anything that sed is better at than ruby. Sed's syntax for a lot of things is very similar to Ruby sub and gsub string methods. I guess I would point you to Ruby unless you really have no other use for a scripting language other than text processing. You could probably get a reasonable understanding of how to use sed a little quicker than how to do the same stuff in ruby.
Sed - an Introduction and Tutorial
O'Reilly Sed & Awk book
I would encourage you to take a look at Perl for tasks like this. Many of Perl's features are designed expressly with the goal of "processing text with concise syntax". It can of course jump over into cryptic, but so can Ruby.
Perl also has extensive support for one line programs typed into the shell. echo "hello world" | perl -lpe 's/\b(.)/\U$1/g' prints Hello World
Forget sed, anything more than a simple, line-oriented search and replace is just unreadable. Learn Awk. And then learn Ruby too: it's good for your soul.
I know the question is very subjective. But I cannot form the question in a much more better manner. I would appreciate some guidance.
I often as a developer feel how easier it would have been for me if I could have some tools for doing some reasonably complex task on a log file , or a set of source files, or some data set etc.
Clearly, when the same type of task needs to be done repetitively and when speed is critical, I can think of writing it in C++/Java.
But most of the times, it is some kind of text processing or file searching activity that I want to do only once just to perform a quick check or to do some preliminary analysis etc. In such cases, I would be better off doing the task manually rather than writing in C++/Java. But I could surely doing it in seconds if I knew some language like Bash/Python/Perl/Ruby/Sed/Awk.
I know this whole question is subjective and there is no objective definite answer, but in general what does the developer community feel as a whole? What subset of these languages should I know so that I can do all these kinds of tasks easily and improve my productivity.
Would Perl be a good choice?
It is a super set of Sed/Awk, plus it allows to write terse code. I can get done with fewer lines of code. It is neither readable nor easily maintainable, but I never wanted those features anyway.
The only thing that bothers me is the negative publiciity that Perl has got lately and it has been criticized by the Ruby/Python community a lot. Also, I am not sure if it can replace bash scripting totally.
If not, then is Perl+Bash a good combination for these kind of tasks?
I tend to do a lot of processing with ruby. It has all the functionality of perl, but I find it to be a little more readable. Both perl and ruby support the -n, -e, and -p options.
-e 'command' one line of script. Several -e's allowed. Omit [programfile]
-n assume 'while gets(); ... end' loop around your script
-p assume loop like -n but print line also like sed
For example in ruby
seq 1 4 | ruby -ne 'BEGIN{ $product = 1 }; $product *= $_.to_i; END { puts $product }'
24
Which is very similar to perl
seq 1 4 | perl -ne 'BEGIN{ $product = 1 }; $product *= $_; END { print $product }'
24
In Python, the same would look like this:
seq 1 4 | python -c 'import sys; print reduce(lambda x,y : int(x)*int(y), sys.stdin.read().splitlines(True))'
24
While it's possible to do the above in bash/awk/sed, you'll be limited by their lack of more advanced features.
Python is more expressive and readable than bash, but requires more setup: import os and so on. For simple tasks, bash is quicker -- which is the most important for this. And don't underestimate the power of input/output redirection in bash!
I would use Perl over a bash/sed/awk combination. Why ?
You only have the one executable, rather than spawning off multiple executables to do work.
You can make use of a wide range of Perl modules to do most anything (see CPAN for the modules available)
In fact I would recommend any scripting language over the shell/awk/sed combination, for the same reasons. I don't have a problem with sed/awk per se, but as your required solutions become more complex/lengthy, I find the more powerful scripting languages more scalable, and (to some degree) refactorable for re-use.
I find Python+Bash a very nice combo.
I usually use Python because it's very readable and maintainable. And because there are lots of online documentation available.
Btw, I suggest you to read http://www.ibm.com/developerworks/aix/library/au-python/
With shell scripting, all you ever need to know is a bit bash/sh and a lot of awk. Bash for calling your commands, and awk for processing. Some of the unix tools below, contrary to the fact that many people use them, are not necessary because awk can do their functions.
1) cut
2) sed
3) wc
4) (e)grep
5) cat
6) head
7) etc..
and a few others whose functions overlap. In the end, your script will not cluttered with redundant tools and slow down your script.
Perl/Python are very useful sysadmin tools as well. Both of them do similar things and have libraries that help in your sysadmin tasks. The only significant difference is, aesthetically speaking, the appearance of your code written in them.
You can learn about Ruby if you want, but in terms of sysadmin, I would say go for Perl/Python instead.
In the time it took you to write those few paragraphs, you could have already learned enough Python to make your life significantly better.
Anyone who already knows C++ or Java can become productive in Python in about 4 hours. Just read the tutorial.
My first port of call is bash with sed to provide regular expression processing. You can do a lot with a bash for loop, grep and some regular expressions.
It's worth learning regular expressions if you don't already know them. An editor which lets you use them (like vi) is extremely useful when manipulating files (e.g. you have a set of data extracted from a logfile, and you need to turn it into a set of SQL statements for example).
If it takes me more than a few minutes to figure out how to do whatever parsing task I'm trying to do in bash/sed, I usually end up using perl instead. As suggested by ikkebr, python is probably as good as (or better than) perl; I just had the misfortune to learn perl first, so am much more familiar with it - if I was to start again, I'd learn python instead I think.
Do you know if there's any tool for compiling bash scripts?
It doesn't matter if that tool is just a translator (for example, something that converts a bash script to a C program), as long as the translated result can be compiled.
I'm looking for something like shc (it's just an example -- I know that shc doesn't work as a compiler). Are there any other similar tools?
A Google search brings up CCsh, but it will set you back $50 per machine for a license.
The documentation says that CCsh compiles Bourne Shell (not bash ...) scripts to C code and that it understands how to replicate the functionality of 50 odd standard commands avoiding the need to fork them.
But CCsh is not open source, so if it doesn't do what you need (or expect) you won't be able to look at the source code to figure out why.
I don't think you're going to find anything, because you can't really "compile" a shell script. You could write a simple script that converts all lines to calls to system(3), then "compile" that as a C program, but this wouldn't have a major performance boost over anything you're currently using, and might not handle variables correctly. Don't do this.
The problem with "compiling" a shell script is that shell scripts just call external programs.
In theory you could actually get a good performance boost.
Think of all the
if [ x"$MYVAR" == x"TheResult" ]; then echo "TheResult Happened" fi
(note invocation of test, then echo, as well as the interpreting needed to be done.)
which could be replaced by
if ( !strcmp(myvar, "TheResult") ) printf("TheResult Happened");
In C: no process launching, no having to do path searching. Lots of goodness.
It's my understanding that there's no "bridge" between Ruby and Perl to let you call into Perl functions directly from Ruby. It's also my understanding that to call a Perl program from Ruby, you simply put it in backticks(i.e. result = `./helloWorld.pl`). However, this doesn't allow interaction with the Perl program(i.e. you can't interact with prompts or provide input). My quesitons are as follows:
Is there any way to provide input to Perl programs from Ruby(aside from arguments)?
Am I wrong that there is no bridge between Ruby and Perl? Interacting with a program's stdin seems like the wrong way to go when navigating prompts, and the programs I'm dealing with are well-designed and have libraries with the appropriate Perl functions in them.
There's the Inline::Ruby module, though I don't have any direct experience with it that I can share.
EDIT: I did try it out last night -- here's the review: Inline::Ruby was last updated in 2002, when v5.6 was the latest stable release. Docs say it has only been tested on Linux; I was trying to use it with v5.10.1 on Cygwin. Got it to build after some hacking of the XS/C code that comes with the module. Passed some unit tests but failed others. Seemed to import Ruby class's into Perl's namespace ok but was less successful importing standalone functions. Summary: if you need a quick and dirty bridge for Perl and Ruby, Inline::Ruby will probably disappoint you. If you have the patience to figure out how to build the module on your system, and to massage your Ruby code to work with the module, you could find it useful.
Use Ruby's exec()
rubypl.rb
#!/usr/bin/ruby -w
script = 'perlscript.pl'
exec("/usr/bin/perl #{script}")
perlscript.pl
#!/usr/bin/perl -w
use strict;
print "Please enter your name: ";
my $name = <STDIN>;
chop($name);
if ($name eq "")
{
print "You did not enter a name!\n";
exit(1);
} else {
print "Hello there, " . $name . "\n";
exit(0);
}
perldoc perlipc states:
DESCRIPTION
The basic IPC facilities of Perl are built out of the good old Unix
signals, named pipes, pipe opens, the Berkeley socket routines, and
SysV IPC calls. Each is used in slightly different situations.
Ruby is capable of operating each of these.
Here's how ruby can use a python script, interacting with the script's stdin and stdout.
foo.py reads two integers (each on its own line) from standard input, adds them, and writes the result to standard-out. I don't know perl, so be nice to me:
#!/usr/bin/perl
$a = <STDIN>;
$b = <STDIN>;
$c = int($a) + int($b);
print $c;
foo.rb executes foo.py, giving it two numbers to add, getting back the result and printing it:
#!/usr/bin/ruby1.8
a = 1
b = 2
c = IO.popen('./foo.py', 'w+') do |pipe|
pipe.puts(a)
pipe.puts(b)
pipe.close_write
pipe.read
end
raise "foo.py failed" unless $? != 0
print "#{a} + #{b} = #{c}" # => 1 + 2 = 3
What you want doesn't really exist, to my knowledge.
The closest thing to what you want, on a generic level, is XDebug. It turns a process into a little server that will accept debugging commands. This is generally used for debugging and profiling and not as interprocess communication, but its a possibility. I believe ActiveState's Perl can be run as an XDebug server.
Otherwise, you need explicitly program in some sort of side-channel that your Perl program listens to for commands (which is what XDebug does). It can be as simple as opening a socket that reads a string, evals it, encodes the result as YAML (or whatever) and writes it back. A REPL, but on a socket rather than on a terminal.
There are, obviously, security implications which will be left as an exercise for the reader. You also don't want listening to the socket to interrupt the program so you will now need something event-driven or threaded.
Sorry I don't have anything more specific. It would make a great CPAN module.
Perl and Ruby both have various "glues". Perl programs using the Expect module can do a lot more than just "wait for output". More likely though, you could communicate with a well-known protocol like HTTP... a Ruby daemon could put up a listener, and Perl could contact it, or vice versa.
But no, you can't just "embed" ruby code into Perl, or vice versa. You've got to run separate processes and communicate somehow.
Try Open4 . It is not designed specific for interacting with perl but with any program that need input and ouput. I am still learning to use it ,but I feel it might suit your need.
You mentioned in one of your comments that you want to run Perl code inside Ruby. This will not work unless you can make the Ruby interpreter understand Perl syntax. Can I get a BNF/yacc/RE for the Perl language? will help you understand the challenges you will face.