I just updated my ruby version and now when I run irb in command line, I get this weird:
1.9.2p290 :001 >
every line. Before it was a simple >
How can I get it back again?
You can edit your ~/.irbrc file to change the prompt (command line prefix). See this answer for an example. You could put this in there to start:
IRB.conf[:PROMPT][:CUSTOM] = {:PROMPT_I => ">> "}
IRB.conf[:PROMPT_MODE] = :CUSTOM
IRB.conf[:AUTO_INDENT] = true
.irbrc is a Ruby script that irb runs when it starts up that lets you configure your prompt.
From this article, in your user dir ~/, create the .irbrc file with following:
IRB.conf[:PROMPT][:MY_PROMPT] = { # name of prompt mode
:PROMPT_I => ">", # normal prompt
:PROMPT_S => nil, # prompt for continuated strings
:PROMPT_C => nil, # prompt for continuated statement
:RETURN => "=> %s\n" # format to return value
}
IRB.conf[:PROMPT_MODE] = :MY_PROMPT
Related
I'm trying to read the content of a file (myfile.txt) through ARGV in Ruby. Here is my code:
filename = ARGV.first
puts "Here's your file #{filename}:"
print txt.read
What I have to do to pass the name of the file to ARGV?
Solution
With a ruby script called read_file.rb :
# read_file.rb
# example :
# ruby read_file.rb some_file.txt
filename = ARGV.first
puts "Here's your file #{filename}:"
print File.read(filename)
You can call :
ruby read_file.rb myfile.txt
Your code
print txt.read
txt isn't defined. If you meant filename, filename is a String which contains a filename. It's not a File object, so you cannot call filename.read directly.
Best use
ARGF.read
Notice the spelling with an ...F
ARGF is a stream of either all files named in the arguments, or standard input if no file has been named. This is best practice for scripts and allows your program to be used with a unix pipe.
cat filename | ruby script.rb
ruby script.rb filename
Will both work and do the same if you use ARGF.
Try the following.
file = ARGV.first
file_name_with_extn = File.basename file # => "abc.mp4"
file_extn = File.extname file # => ".mp4"
file_name = File.basename file, extn # => "abc"
file_path = File.dirname file # => "/path/"
I have the following code in test.rb:
require 'open3'
cmd = 'C:\Program Files\foo\bar.exe'
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
puts "stdout: #{stdout.read}"
puts "\n\n"
puts "stderr: #{stderr.read}"
end
bar.exe is a console application that I created, located in C:\Program Files\foo\. When I run bar.exe:
it outputs "Hello world!"
with any argument, like bar.exe /blah, it outputs a help message.
When I run ruby test.rb I get this error:
C:\RailsInstaller/Ruby2.2.0/lib/ruby/2.2.0/open3.rb:193:in 'spawn': No such file or directory - C:\Program Files\foo\bar.exe (Errno::ENOENT)
from C:\RailsInstaller/Ruby2.2.0/lib/ruby/2.2.0/open3.rb:193:in 'popen_run'
from C:\RailsInstaller/Ruby2.2.0/lib/ruby/2.2.0/open3.rb:193:in 'popen3'
from test.rb:3:in '<main>'
If I change the code to call popen3:
Open3.popen3(cmd, '')
I don't get the Errno::ENOENT error, instead I get the help message, but I want the "Hello World" output.
I searched for a solution but nothing is working, including the answer to "Why does Open3.popen3 return wrong error when executable is missing?".
Why am I getting this error and how do I solve it?
Meditate on this:
cmd = "\P\f\b"
cmd.size # => 3
cmd.chars # => ["P", "\f", "\b"]
cmd.chars.map(&:ord) # => [80, 12, 8]
cmd = "\\P\\f\\b"
cmd.size # => 6
cmd.chars # => ["\\", "P", "\\", "f", "\\", "b"]
cmd.chars.map(&:ord) # => [92, 80, 92, 102, 92, 98]
cmd = '\P\f\b'
cmd.size # => 6
cmd.chars # => ["\\", "P", "\\", "f", "\\", "b"]
cmd.chars.map(&:ord) # => [92, 80, 92, 102, 92, 98]
You're using a double-quoted string with single backslashes as path/directory separators as in the first example. The single back-slashed \f and \b are escaped characters in a double-quoted string, and are not recognized as they were typed using \ f or \ b.
You have two ways of dealing with this, either escaping the backslashes as in the second example, or by using a single-quoted string, as in the third example. It's considered messy to use the second means so use the last for readability and easier maintenance. You get the same characters with less visual noise. This is applicable to string use in most langauges.
The second thing to know is that Ruby doesn't need reverse-slashes as path delimiters. The IO documentation says:
Ruby will convert pathnames between different operating system conventions if possible. For instance, on a Windows system the filename "/gumby/ruby/test.rb" will be opened as "\gumby\ruby\test.rb". When specifying a Windows-style filename in a Ruby string, remember to escape the backslashes:
"c:\\gumby\\ruby\\test.rb"
Our examples here will use the Unix-style forward slashes; File::ALT_SEPARATOR can be used to get the platform-specific separator character.
Finally, you should look at Ruby's Shell and Shellwords in the STDLib. They're your friends.
You are having trouble because "Program Files" is a folder with a space in it. Whenever that happens, you need to double quote it, just as you would on a cmd.exe prompt. And when you're double-quoting, you must remember that your backslash character "\" is an escape character, so you have to double-backslash to get the proper folder separators for Windows. I'm going to use code which actually returns something in my environment; adjust it to your taste. So your code should look like:
require 'open3'
cmd = "\"C:\\Program Files\\Git\\bin\\git.exe\""
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
puts "stdout: #{stdout.read}"
puts "\n\n"
puts "stderr: #{stderr.read}"
end
If you have command line parameters to pass to git, you'd do it like this:
require 'open3'
cmd = "\"C:\\Program Files\\Git\\bin\\git.exe\" --version"
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
puts "stdout: #{stdout.read}"
puts "\n\n"
puts "stderr: #{stderr.read}"
end
Use Open3.popen3([bin, bin]) to prevent shell command handling for a single argument to popen3 (and related methods like spawn).
As you noticed, multiple args can be passed normally without invoking a shell (e.g.
Open3.popen3(bin, arg1, arg2)).
What's the best way to optionally specify an output file but use stdout by default?
Right now I'm trying:
opts = Trollop::options do
opt :output, "Output File", :default => $stdout
opt :input, "Input File", :default => $stdin
end
But when I try using it, I get:
$ ./test.rb -o temp.txt
Error: file or url for option '-o' cannot be opened: No such file or directory - temp.txt.
Try --help for help.
Obviously I don't want to require the output file to exist prior to running my script.
(Also, is the way I'm specifying the input okay?)
Looking at the code in trollop (specifically parse_io_parameter) I believe that currently, trollop (version 1.16.2) assumes any IO type argument (as in the question) is assumed to be for input.
The workaround is as follows.
Use a String to specify the output file in trollop:
opts = Trollop::options do
opt :input, "Input File", :default => $stdin
opt :output, "Output File", :default => "<stdout>"
end
Create an output object (out) based on the parsed argument:
out = if opts[:output] =~ /^<?stdout>?$/i
$stdout
else
fd = IO.sysopen(opts[:output], "w")
a = IO.new(fd, "w")
end
Then you can use it like this:
out.puts("this text gets written to output")
I have a Ruby script that defines a class. I would like the script to execute the statement
BoolParser.generate :file_base=>'bool_parser'
only when the script is invoked as an executable, not when it is require'd from irb (or passed on the command line via -r). What can I wrap around the statement above to prevent it from executing whenever my Ruby file is loaded?
The condition $0 == __FILE__ ...
!/usr/bin/ruby1.8
class BoolParser
def self.generate(args)
p ['BoolParser.generate', args]
end
end
if $0 == __FILE__
BoolParser.generate(:file_base=>__FILE__)
end
... is true when the script is run from the command line...
$ /tmp/foo.rb
["BoolParser.generate", {:file_base=>"/tmp/foo.rb"}]
... but false when the file is required or loaded by another ruby script.
$ irb1.8
irb(main):001:0> require '/tmp/foo'
=> true
irb(main):002:0>
use $0
in irb the value of $0 is "irb"
in your file is "/path/to/file"
an explanation here
Ruby is preinstalled on my Mac and so I wanted to have a look at it. First thing I noticed, is that irb prompts >> instead of irb(main):001:0>. I can't find anything on how to change this with Google because everyone is using irb(main):001:0> in their code ;-)
Can you help me out?
PS: It's not that I think Ruby is broken, but I want to look more nerdy while programming ;-)
$ irb --help
Usage: irb.rb [options] [programfile] [arguments]
--prompt prompt-mode
--prompt-mode prompt-mode
Switch prompt mode. Pre-defined prompt modes are
`default', `simple', `xmp' and `inf-ruby'
$ irb --prompt inf-ruby
irb(main):001:0>
What I do is make that into an alias in my .bashrc so I don't have to type it every time.
echo alias irb=\'irb --prompt inf-ruby\' >> ~/.bashrc
Hope this helps!
goto the location /home/leapfrog/.rvm/scripts
cd ~/.rvm/scripts
Open the file ‘irbrc.rb’, use superuser power to over-write the
$ sudo gedit irbrc.rb
Change the content of the hash '#prompt' to the following
#prompt = {
:PROMPT_I => "#{rvm_ruby_string} :%03n > ", # default prompt
:PROMPT_S => "#{rvm_ruby_string} :%03n%l> ", # known continuation
:PROMPT_C => "#{rvm_ruby_string} :%03n > ",
:PROMPT_N => "#{rvm_ruby_string} :%03n?> ", # unknown continuation
:RETURN => " => %s \n",
:AUTO_INDENT => true
}
Hope this help you :)