Running Ruby scripts in Atom or command shell - ruby

complete Ruby amateur here. After playing around with Ruby on various interactive online coding environments, I thought I'd try to set up Ruby on my Windows in the same way I've set up Python (using Atom and Terminal-Plus). After being frustrated and Googling for answers the past 3 hours, I thought I'd bring my question here.
Using Python, I can save a file (test.py) in Atom, and execute it using Terminal-Plus by typing:
py -i test.py
And this would create an interactive shell where I can call any functions I've stored inside my test Python script. I've learnt that I can do a similar thing with Ruby (for a test file test.rb) using:
ruby -r test.rb
but this yields the following error:
C:/Ruby21- x64/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such
file -- test.rb (LoadError)
from C:/Ruby21-x64/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
The same thing happens if I use cmd prompt to try and execute the script. I've seen other problems like this where the person was missing a key RubyGem that they were trying to call, but my test.rb file is literally:
def xyz
for i in 1..100
puts i
end
end
I'm just trying to call a Ruby script and be able to call the functions I've stored in the script in the console, in this case xyz.

-r command line switch is used to use require to load lib as a library before executing.
Try
ruby test.rb
from inside the directory this file is located, it should work.

Related

how to build wrapper script

Sort of an odd question, but: how would one go about creating a wrapper shell script that can be used in the #! line in other scripts.
wrap.sh
#!/bin/bash
set -e
echo "wrapper!"
exec ruby "$#"
test.rb
#!/usr/bin/env wrap.sh
puts RUBY_VERSION
puts "the ducks come from the trucks"
wrap.sh is in the path, and test.rb is marked as executable.
Now I do:
./test.rb
wrapper!
ruby: no Ruby script found in input (LoadError)
The goal is to execute the ruby script via the wrapper (The ruby version can be either local or comes from a traveling ruby install that is shipped along with the app).
As far as I can tell ruby is invoked, it's just unhappy with the #! in the test.rb and refuses to run the script. I cannot remove the #! because that's how the script is executed in the first place.
Any workarounds for this?
So, I cannot use rbenv/rvm/etc. There is more logic in the wrapper than this, but this is the gist of it.
Looks to me like the arguments are not being passed to Ruby in "$#". I don't think the bang-hash line is the problem.
I don't see anything in your script which actually passes the contents of test.rb to wrapper.sh, which is the bigger issue.
Perhaps the real problem can be solved by some other means? For example, is the problem you're trying to solve to run arbitrary commands prior to the invocation of any Ruby script from the command line? Perhaps it can be approached that way...
It looks like Ruby just checks that the hash-bang line contains "ruby": https://github.com/ruby/ruby/blob/v2_2_2/ruby.c#L1580 So basically having ruby somewhere in the #! line is all it takes.

Ruby - How to use -r switch with ruby command line tool

I was trying to figure out how to work the command line switch -r.
My understanding is that the code is typed out as follows:
ruby -r*nameOfRequired*
I am finding that this is not the case. When I type out the above and press enter, the terminal expects an "end of input syntax" and does not continue.
What am I missing? Does there need to be a space in between the switch and the name of the required file?
Please and thank you!
EDIT:
I am currently reading "The Well Grounded Rubyist" by David A. Black, and I came up with this question while reading the section on command line switches.
Having said that, I created a "test.rb" file, containing:
puts Date.today
Then, in the terminal, I typed out:
ruby -r date
I thought this would 'require' the date module, and then enable me to run the "test.rb" file, using ruby test.rb (given that I am in the correct directory).
Instead, the terminal cursor moves to a newline, expecting more input. Let me know if I need to clarify anything else. Thanks!
If you just type ruby -rmodule, then Ruby will load the module and wait for you to type the main program that requires that module.
If you just want to run the module and do nothing else, you can do do rubyfull-path-to-module without the -r, or ruby -rmodule -e exit, or ruby -rmodule </dev/null, or similar.
In general, the ruby command does not record any state from one run to the next, so you need to tell it every thing that it needs to know whenever you run it.
Whenever you run it, you need to tell it the main program to run or else it will expect you to type that program on the standard input. The -r does not specify the main program.
Try this:
ruby -rdate test.rb
According to ruby -h:
-rlibrary require the library, before executing your script
Without giving your script file path, it read the script from stdin.
Try following (You can omit script file path when you give -e command):
ruby -r**nameOfRequired** -e ""

How to find files in ruby which were edited in some time interval?

How to find files in a directory which were edited in last n minutes?
In unix which is -mmin -60.
In host
ruby /home/ava/test works fine!
Net::SSH.start('host', 'ava') do |ssh|
`ruby /home/ava/test`
end
gives ruby: No such file or directory -- /home/ava/test (LoadError)
You could get a list of files using Dir.[], and use File.mtime on each one to filter them:
Dir["*"].select { |fname| File.mtime(fname) > (Time.now - 60) }
The problem with your code is that Ruby isn't control on the remote system you connect to, instead, the shell on that system is, and you're merely able to issue commands, as if you'd ssh'd into your own local system. Ruby's built-in commands, like Dir.chdir only apply locally, not to the remote session.
Your best bet is to write a script you execute that resides on that system, otherwise the task of executing commands becomes more difficult and you'll need to anticipate prompts and possibly various responses from commands on that system as your code executes things.
The Net::SSH gem includes examples showing how to issue remote commands; You need to remember that once you've connected you're issuing commands to the shell, not to Ruby.
Net::SSH.start('host', 'ava') do |ssh|
`ruby /home/ava/test`
end
gives ruby: No such file or directory -- /home/ava/test (LoadError)
The best way to diagnose this is to start by SSHing to your own local box and executing the code locally, or using surrogate code that only echoes the commands you'd be using in real life on the other machine. Then you can test to see if the actions would be called.
Instead of:
ruby /home/ava/test
issue a command like:
ls -al /home/ava
first, to see what files are visible.
Follow that with something like:
ruby -pe '%x(ls /home/ava)'
to see if Ruby is found and it can execute that command in the path.
Dealing with remote systems isn't the same as running scripts locally. Your environment can be different, meaning your PATH or variables you expect might not be the same.

How to turn on STDOUT.sync in ruby from the command line

I have objective-C code that calls ruby scripts and monitors STDOUT. However, ruby does not seem to synchronise STDOUT by default, so I need to put STDOUT.sync = true at the beginning of the script to see output as it happens.
Can I do this as a command line option when calling a ruby script?
You can create a setup file to require before your script. Then call ruby with the -r flag:
ruby -r "$HOME/.rubyopts.rb" myscript.rb
You can also set the environment variable RUBYOPT to automatically include that file every time you run ruby:
export RUBYOPT="-r $HOME/.rubyopts.rb"

Automatically require a class when running / starting ruby

I am doing some monkey patching in some of Ruby classes and I would like that to be included AUTOMATICALLY whenever I run ruby.
For example:
I added the method trim to String. I want to be able to do this:
ruby -e 'puts " aaaa ".trim'
I don't want to do this:
ruby -e 'require "monkey.rb"; puts " aaaa ".trim'
Is there anyway to include my monkey patches evertime I start ruby? How about irb?
Thanks!
ruby and irb both take a -r option that lets you specify a library to load when running those executables. If you want to automatically load your monkey.rb library, you can start ruby with the invocation $ ruby -r monkey (assuming monkey.rb is in your $RUBYLIB path. If you don't want to do that each time, you can set up an alias in your shell config file. For example (in Bash), you could add:
alias ruby='ruby -r monkey'
irb is probably the place where you can do this most simply. When using irb, you can use an initialization file to store anything you want run on every startup. In your home directory ("cd ~"), create a file called ".irbrc", and drop in your "require 'monkey.rb'" statement, that should do it. From then on when you start up irb, it will run anything in that script first.

Resources