Show HN: Rb – Turns Ruby into a command line utility

By redka - 2 days ago

Showing first level comment(s)

Interesting, so it's reading text from STDIN into an Array, then executing its arguments as Ruby code in the context of that Array (or if you pass -l, in the context of each line individually). So all the standard methods on the [Array][1] (or [String][2]) class become accessible as top-level methods.

A few examples:

Capitalizing a line:

   echo hello world | rb -l capitalize
Printing only unique lines:

    printf 'hello\nworld\nhello\n' | rb uniq
Computing the sum of numbers in a table:

   printf '1\n2\n3\n' | rb 'map(&:to_i).sum'
Personally I think it's a really cool idea.

[1]: https://ruby-doc.org/core/Array.html

[2]: https://ruby-doc.org/core/String.html

Ajedi32 - 2 days ago

It makes me a little uncomfortable that they're using curl|bash for something as simple as "put this 10-line script somewhere in your $PATH," especially when the script involves sudo (to move into /usr/local/bin). Sure, it's easy to inspect the script and see that it's not doing anything malicious, but it makes install processes like this, where it'd be incredibly easy to, seem normal.

KeyboardFire - 2 days ago

The second I start wanting a bash pipeline, probably around the third pipe, I scrap it immediately and move to using a text editor to write a script. Because if I'm wanting a pipeline, I'm also going to want to store it, and transmit it over the network, and manage it, and put it down and come back to it later.

All things perfectly manageable inside a PORO. Bundler even has an inline mode, so you can put everything in one file, close to your data, Bundler just handles dep management under the hood like a boss. Check out bundler-inline.

Sure, you can do all that with bash. But you can also make system() calls with Ruby, with full string interpolation power tools. If you're a Rubyist, and you want to do data analysis, this is the workflow you want.

vinceguidry - 2 days ago

The command should process stdin in streaming fashion rather than slurping it all at once:

  code = ARGV[0]
  STDIN.each_line do |l|
    puts l.instance_eval(code)
    STDOUT.flush
  end

pulisse - 2 days ago

Command line tools in 10 lines of ruby (using this script):

    docker ps | rb drop 1 | rb -l split[1]
    docker ps -a | rb grep /Exited/ | rb -l 'split.last.ljust(20) + " => " + split(/ {2,}/)[-2]'
    df -h | rb 'drop(1).sort_by { |l| l.split[-2].to_f }'
Command line tools in zero lines of ruby (using ruby):

    docker ps | ruby -lane 'next if $. == 1; print $F[1]
    docker ps -a | ruby -lne 'print $1 if /(Exited .*? ago)/'
    df | ruby -lane 'BEGIN { lines = [] }; lines.push [$F[4].to_i, $_] if $. > 0; END { lines.sort { |a,b|b[0] <=> a[0] }.each{|k| print k[1] } }
Bit of a pain as ++ is lacking, as is autovivication. a /bin/sort at the end usually beats `<=>` for terseness.

star-techate - 2 days ago

  $ docker ps | rb drop 1 | rb -l split[1]
  $ docker ps | perl -anE 'say $F[1] if $.>1'

perl solved this problem a long time ago, people

perlperson - 2 days ago

A bashtardization:

    rb () {
      [[ $1 == -l ]] && shift
      case $? in
        0 ) ruby -e "STDIN.each_line { |l| puts l.chomp.instance_eval(&eval('Proc.new { $* }')) }";;
        * ) ruby -e "puts STDIN.each_line.instance_eval(&eval('Proc.new { $* }'))";;
      esac
    }

binaryphile - 8 hours ago

"pyped" does the same for python.

I though it was great, knowing python better than bash, plus it was portable to windows.

But eventually I always end up using built in GNU tools.

Don't know why. It just rolls better.

sametmax - 2 days ago

What does this have over the default ruby?

cat your-file.txt | ruby -ne '$_.your_ruby_stuff'

Just syntactic sugar? (it does look cleaner!)

meow_mix - 2 days ago

“With 10 lines of Ruby replace most of the command line tools that you use to process text inside of the terminal.”

Well, it’s these 10 lines, plus an unlimited amount of Ruby that you have to compose on the fly for each operation.

code_duck - 2 days ago