How can a Ruby script detect that it is running in irb? - ruby

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

Related

How to pass array as an argument to a Ruby function from command line?

I want to call Ruby function from command line with array as an argument.
Script name is test.rb
In below code Environments are like test,dev,uat.', am passing as ['test','dev','uat']
I have tried as below:
ruby -r "./test.rb" -e "start_services '['dev','test','uat']','developer','welcome123'"
def start_services(environments,node_user_name,node_password)
environments.each do |env|
puts env
end
puts node_user_name
puts node_password
end
Output:
-e:1: syntax error, unexpected tIDENTIFIER, expecting end-of-input start_services '['dev','test','uat']','developer',' ^
You clearly want to pass an array as the first parameter into start_services method, so you should do it like this:
$ ruby -r "./test.rb" -e "start_services ['dev','test','uat'],'developer','welcome123'"
# output:
dev
test
uat
developer
welcome123
What you've been trying so far was attempt to pass '[\'dev\',\'test\',\'uat\']' string, which was malformed, because you didn't escape ' characters.
Don't pass your credentials as arguments, any user on your system would be able to see them.
Instead, you could save them as environment variables or in a config file.
if ARGV.size == 0
puts "Here's how to launch this script : ruby #{__FILE__} env_name1 env_name2 ..."
exit
end
# Define those environment variables before launching the script.
# Alternative : write credentials in a json or yml file.
node_username = ENV["NODE_USERNAME"]
node_password = ENV["NODE_PASSWORD"]
ARGV.each do |env|
puts "Launching environment #{env}"
end

Ruby frozen string literal pragma order caused error

Given a file with Ruby 2.3.0p0:
#!/usr/bin/env ruby
# frozen_string_literal: true
# Exit cleanly from an early interrupt
Signal.trap("INT") { abort }
This is fine.
# frozen_string_literal: true
#!/usr/bin/env ruby
# Exit cleanly from an early interrupt
Signal.trap("INT") { abort }
will result in error:
syntax error near unexpected token `"INT"'
`Signal.trap("INT") { abort }'
Why?
A shebang has to appear on the file's initial line.
A file test.rb containing:
#!/usr/bin/env ruby
# foo bar
puts "hello from #{RbConfig.ruby}"
will be run via Ruby:
$ ./test.rb
hello from /.../ruby-2.3.0/bin/ruby
But if test.rb contains: (1st and 2nd line swapped)
# foo bar
#!/usr/bin/env ruby
echo "hello from $SHELL"
it will be run as an ordinary shell script:
$ ./test.rb
hello from /.../bin/zsh
Therefore, the error you are getting is no Ruby error, it's from your shell.

How do i run Ruby script from command line ?

I've a file, which I can run from command line using:
ruby filename.rb
Which outputs:
12345
A different script containing:
def hi()
puts "hello"
end
does not return anything when I run it from the command-line.
How do I run this from the command line?
Add puts hi("John") to the bottom of the method:
def hi(name)
puts "hello"
end
puts hi("John")
Where "John" is whatever name you want it to be.
Then just run it as usual, ruby yourfilename.rb
Try putting this in filename.rb:
def hi()
puts "hello"
end
hi
Then run your code in the command line: with ruby filename.rb

Run def in ruby program

I'm a beginner in programming and wrote this little program:
Test.rb:
# encoding: utf-8
require 'open-uri'
require 'nokogiri'
def parse_file
doc = Nokogiri::XML(File.open("test.xml"))
parse_xml(doc)
end
def parse_xml(doc)
doc.root.elements.each do |node|
parse_tracks(node)
end
end
def parse_tracks(node)
if node.node_name.eql? 'kapitel'
puts 'New Kapitel'
end
end
I know how to execute this code:
ruby test.rb
But how can I call the def parse_file?
Simply add whatever you want to the end of your file. Ruby scripts are simply scripts, they are being interpreted:
…
end
parse_file # ⇐ HERE YOU GO
You can either call the method at the end of your test.rb file:
def parse_file
# ...
end
parse_file
And run it with
$ ruby test.rb
Or leave the file as it is, require it as a library and call the method manually:
$ ruby -r test.rb -e "parse_file"
Rather than hard-coding your file path, you can pass it as an argument when calling your script. Arguments can be accessed via the ARGV array:
def parse_file(file)
doc = Nokogiri::XML(File.open(file))
parse_xml(doc)
end
parse_file(ARGV.first)
Now you can run it with:
$ ruby test.rb test.xml
Another option is to make the script executable. Add a shebang as the first line of you file:
#!/usr/bin/env ruby
And set the execute flag:
$ chmod +x test.rb
Now you can run it with:
$ ./test.rb test.xml
just add
parse_file
in the end of your ruby file

Checking if a Ruby program was executed or imported via require

How do you check if a Ruby file was imported via "require" or "load" and not simply executed from the command line?
For example:
Contents of foo.rb:
puts "Hello"
Contents of bar.rb
require 'foo'
Output:
$ ./foo.rb
Hello
$ ./bar.rb
Hello
Basically, I'd like calling bar.rb to not execute the puts call.
Change foo.rb to read:
if __FILE__ == $0
puts "Hello"
end
That checks __FILE__ - the name of the current ruby file - against $0 - the name of the script which is running.
if __FILE__ != $0 #if the file is not the main script which is running
quit #then quit
end
Put this on top of all code in foo.rb
For better readability you can also use $PROGRAM_NAME
if __FILE__ == $PROGRAM_NAME
puts "Executed via CLI #{__FILE__}"
else
puts 'Referred'
end
More info: What does __FILE__ == $PROGRAM_NAME mean in ruby?

Resources