Trouble outputting and inputting information to command line using Ruby sciTE - ruby

I am writing a program in Ruby, but I'm having trouble getting information from the command prompt using the sciTE text editor. For example, when I attempt to run code that requires input from the user (e.g., puts "Please enter your name: " name = gets()), the command line pops up but the information that I "put" to the screen does not show. When I try to enter information (letters or numbers), nothing happens. I then close out the command prompt and receive an error code in the sciTE output window.
Any thoughts?
Thanks!

I do hope I understand what you want to do, but this is a sample here from my irb prompt:
1.9.2-p290 :001 > def a
1.9.2-p290 :002?> puts "what is your name"
1.9.2-p290 :003?> name = gets.chomp
1.9.2-p290 :004?> puts "My name is #{name}"
1.9.2-p290 :005?> end
=> nil
1.9.2-p290 :006 > a
what is your name
abbb
My name is abbb
=> nil
1.9.2-p290 :007 >

I encountered this problem today going through Mr. Neighborly's Ruby tutorial, and worked out the answer. It is a known problem with SciTE and the way it interacts with stdin (gets()) on Windows.
To run the tutorial code as-is, use the command prompt to run your program, rather than the SciTE 'Go' key [F5] mentioned in Mr. Neighborly's Humble Little Ruby Book, as follows:
Workaround 1:
Your Windows Ruby installation should include a shortcut (under the
Start menu) called "Start Command Prompt with Ruby". Run that.
In the Ruby command prompt, navigate to the path where your Hello
World Ruby file is located.
Type ruby hello.rb and press [Enter]. (Replace hello.rb with your file name.)
Workaround 2:
Another alternative is to ignore the broken command prompt, and use SciTE's internal one instead. But, this requires you to add $stdout.flush() after each puts() statement, like this:
puts "Hello, world. What is your name?"
$stdout.flush() # Add this line!
myname = gets()
puts "Well, hello there " + myname + "."
$stdout.flush() # Add this line!
Note
The next inconsistency in Chapter 0 of the tutorial, which you will probably notice immediately, is that the newline (\n) character is included in your myname variable (the input from gets()). You will probably see the following output (note the "." on the second line):
Well, hello there Yournamehere
.
To fix this, change myname.gets() to myname.gets().chomp().
(Feel free to look up chomp() in the online Ruby documentation.)

Related

Ruby hello world in sublime

I am trying to run my first Ruby program. I am using sublime. My programs code is as follows..
$ vim helloworld.rb
#!/usr/bin/ruby
# Hello world ruby program
puts "Hello World!";
I am getting the following output error...
C:/Users/myname/AppData/Roaming/Sublime Text
2/Packages/User/helloworld.rxml:1: `$ ' is not allowed as a global
variable name [Finished in 0.1s with exit code 1]
Can anyone help me, and google search did not turn up much.
Remove $ vim helloworld.rb from the file.
It's a common practice in the books to prefix the commands written in terminal with $, so if you see $ some_cmd, it's most probably written in terminal.

Ruby "gets" does not wait for user input

This is a very silly question, but it doesn't work for me.
I am trying to make the program wait for my input. I tried replacing gets with stdin.gets, and $stdin.gets and when I try gets.chomp I get a nil class exception.
puts "Get works here?"
option = gets
puts option
To work this,you need to call your .rb file from your command prompt. Like say you save your code in a file called test.rb.
test.rb
puts "Get works here?"
option = gets
puts option
Then run from your command prompt:
C:\Users\arup> ruby test.rb
my script was also not waiting for input from gets(), but started to do so when I used
$stdin.gets("\n")

Ruby .gets doesn't work

I'm trying to get simple user input in Ruby, but I can't get it working. I'm using the gets method, but the program never stops to ask me for input. I'm using Sublime Text 2 as my text editor, and I run the program in it, too (if this makes a difference).
Here's my code:
puts "What is your name?"
name = gets
puts "Hello " + name + ". How are you?"
And here's the error (and output) given to me:
C:/Users/Sten Sootla/Desktop/Ruby workspace/exercise.rb:3:in `+': can't convert nil into String (TypeError)
from C:/Users/Sten Sootla/Desktop/Ruby workspace/exercise.rb:3:in `'
What is your name?
[Finished in 0.1s with exit code 1]
Why doesn't the program stop to ask me for input?
Try using $stdin.gets instead of just a plain gets, this will force the input to come from stdin
Here's how I understand it. gets and puts are instance methods of IO, and the default IOs are $stdout and $stdin.
Calls to gets/puts will only be effective if the translator is capable of handling stdout/in e.g. IRB
If you run a ruby file from bash it works too.
io_test.rb
puts gets
in bash
ruby io_test.rb
Then it will "put" into stdout whatever it "gets" from stdin.
If you want to run code within ST2, check out the SublimeREPL plugin, available through Package Control. While you can use IRB, its main Ruby interface is through pry, which is a lot more powerful. You can use it as a classic REPL (think Clojure or LISP), and you can also transfer your code from one tab into the running REPL in another tab by selection, line range, or block.
Interestingly, your code above works in IRB for me, but not pry for some reason - it's reading my $EDITOR environment variable, which is set to subl -w but failing with Errno::ENOENT: No such file or directory - subl -w. Strange...
At any rate, I highly highly recommend SublimeREPL, as it's a really powerful tool, and is self-contained within ST2, so you don't have to keep flipping back and forth to your terminal, saving and reloading your programs.

Ruby's irb with [what?] is equivalent to the Python Shell with IDLE? (On Windows, if relevant.)

This has been a surprisingly hard question to find an answer to.
(A few questions seem to be asking something at least similar, like:
Ruby console alternative for IRB (Windows)
IDLE like interactive console for Ruby
A recommended Ruby interactive console
But I couldn't get what I need from any of those.)
Also, I'm a bit unsure of the precise terminology I should be using, so I'll try to be really concrete here:
Say you're using IDLE with the Python shell.
You have one of IDLE's text-editor windows open with a script "example.py" in it.
You hit F5 and the Python shell comes up and does exactly what it would do if you had just entered every line in "example.py" into the shell line-by-line.
Functionally, that's exactly what it's doing is automatically entering every line, only without cluttering up the screen by displaying them. (Also it resets the shell to a fresh state every time you do this, but that's not really the important point at the moment; Sometimes it'd be nice to have the option of having it not reset the state of the shell, whatever.)
So the outcome is that now you can play around in the shell, and all the functions and variables etc that were in the script that you just ran are all there.
But with irb...
How do I get the same effect?
For instance, I tried irb example.rb (an equivalent ruby script) in the Windows console, and it just literally enters each line one-by-one into irb, spewing them down the screen, then automatically exits back to the Windows command prompt.
(Although even if that did work the way I wanted (is there some option flaggy argument thingy that would make it do more what I want here?), I'd still have to alt-tab from the text-editor to a console window, and enter the command and file name, which is inferior to just pressing F5, obvs.)
To make really sure I'm being clear in what I mean, here are concrete examples of:
1) a Python script for "example.py"
2) an example of running it in the shell then doing some things in the shell (copy-pasted from the actual shell)
3) an equivalent Ruby script to that Python one
4) an example of running it in the kludgy, slow online-interpreter at repl.it, and doing the exact same things in that irb shell (again, copy-pasted)
1) example.py :
x = "some value you don't want to keep reassigning to this variable"
y = "some other value like that"
def some_function(var):
return "do something complicated with `"+var+"`"
print("example.py just ran")
2) Python shell :
Python 3.2.3 (default, Apr 11 2012, 07:15:24) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> ================================ RESTART ================================
>>>
example.py just ran
>>> x
"some value you don't want to keep reassigning to this variable"
>>> y
'some other value like that'
>>> print(some_function(x))
do something complicated with `some value you don't want to keep reassigning to this variable`
>>> x = "a frog"
>>> print(some_function(x))
do something complicated with `a frog`
>>> print("gonna run example.py again")
gonna run example.py again
>>> ================================ RESTART ================================
>>>
example.py just ran
>>> print("x is back to: `\""+x+"\"`")
x is back to: `"some value you don't want to keep reassigning to this variable"`
3) example.rb :
x = "some value you don't want to keep reassigning to this variable"
y = "some other value like that"
def some_function var
"do something complicated with `#{var}`"
end
puts "test.rb just ran"
4) online Ruby irb shell thing at repl.it :
Ruby 1.8.7 (2008-05-31 patchlevel 0) [x86-linux]
[GCC 4.2.1 (LLVM, Emscripten 1.5, Emscripted-Ruby)]
test.rb just ran
=> nil
x
=> "some value you don't want to keep reassigning to this variable"
y
=> "some other value like that"
puts some_function x
do something complicated with `some value you don't want to keep reassigning to this variable`
=> nil
x = "a frog"
=> "a frog"
puts some_function x
do something complicated with `a frog`
=> nil
puts "gonna run this script again..."
gonna run this script again...
=> nil
test.rb just ran
=> nil
puts "x is back to: `\"#{x}\"`"
x is back to: `"some value you don't want to keep reassigning to this variable"`
=> nil
The best answer I've found so far seems to be to install pry (enter gem install pry at the command prompt).
Now if you run a script by entering pry scriptname.rb, and it encounters an exception, it will automatically go interactive.
Furthermore, if you add require 'pry' inside the script at the top, then you can put binding.pry in the script at ay point.
Now when you run the script (simply by entering scriptname.rb at the command prompt), it will stop executing and go interactive in pry at that point.
Pressing ^D (ie, ctrl-d) will resume execution.
Getting a script to run in a command prompt window when you press F5 (or whatever) in your editor (eg, Notepad++) is apparently somewhat trickier. Solutions like this have some problems that I haven't figure out how to tweak away yet.
So currently I'm just alt-tabbing to the command prompt window and running the script from there (again, by entering pry scriptname.rb or just scriptname.rb, depending on what exactly what I want and whether I put a binding.pry in the script anywhere. Up-arrow recall, tab completion, blah blah.)
I'm working on figuring it out.
I am not 100% sure if this is what you want, but from my experience, using ruby scriptname.rb will run the code

Execute shell commands from Ruby code

Note: If you think of a better title/question, feel free to suggest it. I wasn't sure how to articulate this question in one brief sentence.
I created a command line Mastermind game. To play the game, you type play.rb at the command line.
play.rb is a Ruby script that fires up the game. Within the script, the game is sent an interface, called CommandLineInterface.
If you want to play using a GUI (I'm using a Ruby GUI called Limelight), you cd into the limelight directory and type limelight open production and the GUI opens.
There is a mastermind_game directory that contains a lib, a spec, and a limelight directory. The limelight directory contains a production directory.
Now I'm making a few changes. You can pass arguments to the script at the command line. Either you enter play.rb "command line game" or play.rb "limelight game".
ARGV is an array of the arguments passed at the command line.
if ARGV.include?("command line game")
interface = CommandLineInterface.new
elsif ARGV.include?("limelight game")
interface = LimelightInterface.new
end
If I want to play my command line game, I enter play.rb "command line game" and it works fine.
I want to be able to type play.rb "limelight game" at the command line and have that open the GUI. In ARGV, the argument "limelight game" would be found so interface would be set to LimelightInterface.new. Within my LimelightInterface class I want the initialize method to open the GUI. It should essentially have the same functionality as typing limelight open production at the command line.
I'm not sure if this is possible or how to do it, so any help would be appreciated! Thanks!
EDITED: I'm trying to execute the command rvm use jruby by including this line in my script:
system("rvm use jruby")
I get back: "RVM is not a function, selecting rubies with 'rvm use ...' will not work."
Ryan, there's several ways to call out to the system:
Backticks:
ruby -e 'p ARGV' '1 2' '3 4' # => "[\"1 2\", \"3 4\"]\n"
The %x literal (note that you can use any delimiter you like, you're not restricted to parentheses)
%x(ruby -e 'p ARGV' '1 2' '3 4') # => "[\"1 2\", \"3 4\"]\n"
The system command. The difference here is that it passes stdin / out / err on through. (the above return the stdout, this one prints it on your process' stdout).
system('ruby', '-e p ARGV', '1 2', '3 4')
# >> ["1 2", "3 4"]
And if you need more sophisticated usage, something like open3 from the stdlib has gotten me pretty far. If you really need the big guns (it doesn't sound like you do), there's a gem open4.
Edit:
It sounds like you're wanting to do something like this:
require 'open3'
bash_script = <<SCRIPT
source "$HOME/.rvm/scripts/rvm"
rvm use jruby
ruby -v
exit
SCRIPT
out, err, status = Open3.capture3 'bash', stdin_data: bash_script
puts out
# >> Using /Users/joshcheek/.rvm/gems/jruby-1.6.7
# >> jruby 1.6.7 (ruby-1.8.7-p357) (2012-02-22 3e82bc8) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_29) [darwin-x86_64-java]
But honestly, I don't think it's a good solution for your situation, because there's many legitimate ways to set up jruby for your environment. I think it would be better to just check that the limelight binary exists, and tell your user to fix their environment if it doesn't.
Here's the first result from googling the title: http://tech.natemurray.com/2007/03/ruby-shell-commands.html
If that's not what you need, I don't understand the question.

Resources