Looking for an alternative to eval - ruby

I'm new to ruby however it isn't really that drastic of a change coming from perl, anyways 've written a simple script to convert my gobs of perl Data::Dumper output into yaml configs, my problem is I'm using eval to accomplish this and seeing as I may like others to use this script one day I would like to eliminate eval for something more sane.
example:
input file contains
$VAR1 = { 'object' => { 'some_key' => 'some_value' } }
method to read it in
# read in file here ...
eval( stringified_file )
print $VAR1.to_yaml
output
object:
some_key: some_value
Thanks :)

On the Perl side you can output your data structures to YAML (I like YAML::Syck for this), and then read the data in as YAML on the Ruby side. That way you won't need to do an eval.

If for you're unable to change the source application to output YAML, use Kernel#load:
require 'yaml'
load 'dumped_file', true
puts $VAR1.to_yaml

Related

How to make my script use a CSV file that was given in the terminal as a parameter

I tried to google this, but cant really find "good words" to get to my solution. So maybe someone here can help me out.
I have a script (lets call it script.rb) that uses File.read to read a csv file called somefile.csv and i have another csv file called somefileV2.csv.
Script.rb
csv_text = File.read('/home/XXX/XXX/XXX/somefile.csv')
Right now it uses somefile.csv as default, but I would like to know, if it is posseble to make my script use a CSV file that was given in the terminal as a parameter like:
Terminal
home$ script.rb somefileV2
so instead of it reading the file that is in the script, it reads the other csv file (somefileV2.csv) that is in the directory. It is kinda annoying to change the file manually everytime in the script itself.
You can access the parameters (arguments) using the ARGV array.
So your program could be like:
default = "/home/XXX/XXX/XXX/somefile.csv"
csv_text = File.read(ARGV[0] || default)
which gives you the possibility to supply a filename or, if not supplied, use the default value.
ARGV[0] refers to the first, ARGV[1] to the second argument and so on.
ruby myscript.rb foo bar baz would result in ARGV being
´["foo", "bar", "baz"]´. Note that the elements will always be strings. So if you want anything else (Numbers, Date, ...) you need to process it accordingly in your program.

Is there a %*SUB-MAIN-OPTS pair for short option processing?

The multi sub MAIN() command line parsing in Perl6 is sweet!
As far as I can tell from the Command Line Interface docs there is only one option supported in the dynamic hash %*SUB-MAIN-OPTS to manipulate the option processing (that being :named-anywhere).
Perhaps I've missed the obvious, but is there an existing/supported option to take 'old fashioned' single dash options?
For example:
#Instead of this...
myprogram.p6 --alpha=value1 --beta==value2 --chi
#... short options like this
myprogram.p6 -a value1 -bvalue2 -c
Or is this best processed manually or with an external module?
You can sort of emulate this as-is, although you still have to an = ala -a=foo, and still technically have --a=foo in addition to --alpha and -a
sub MAIN(:a(:$alpha)!) {
say $alpha;
}
...so you probably want to use https://github.com/Leont/getopt-long6
use Getopt::Long;
get-options("alpha=a" => my $alpha);

How to execute a Ruby code from inside a Ruby script?

I'm trying to execute a Ruby script file.
Assuming the input is a string that contains the file content.
What are the possible ways? taking into considerations that I need to keep the output of the executed file whether stdout or not separated from the Main script.
As an example of what I'm trying to do is have a function called execute(code)
Then calling execute('4 + 5') would return 9 although I can write a whole Ruby script in the place of '4 + 5'.
If anyone can forward me to any related tutorials or books, I'd be thankful :)
You can call shell commands in Ruby, it's as simple and intuitive as surrounding your desired command in backticks.
The output gets returned, so just save it to a variable:
script1.rb:
puts "asdf"
script2.rb:
output = `ruby script1.rb`
puts output
"asdf"
I question what exactly it is you're trying to do, though. Because this is totally unintuitive and roundabout. Are you sure you aren't just looking for a module or something?

Convert array to arguments for shell command

I'm trying to do something like:
list = Dir["*.mp4"]
`zip "test.zip" "#{list}"`
But #{list} is coming out as an array, how do I fix that?
You should use Shellwords from the standard library, which is designed to do exactly this—and does proper escaping no matter how weird your filenames are:
require 'shellwords'
list = Dir["*.mp4"]
puts [ "zip", "test.zip", *list ].shelljoin
# => zip test.zip foo.mp4 filename\ with\ spaces.mp4 etc.mp4
Doesn't look like you're storing the result anywhere so you should use the multi-argument form of system and bypass the shell entirely:
system('zip', 'test.zip', *list)
Since no shell is invoked, you don't have to worry about quoting or parsing or any of that nonsense, just build a list of strings and splat it.
If you do need to capture the output, then use one of the Open3 methods. Backticks are almost always the wrong approach, there are too many sharp edges (just browse the CERT reports for Ruby and you'll see how often backticks and the single argument form of system cause problems).
http://www.ruby-doc.org/core-2.1.2/Array.html#method-i-join
You are looking for the join method
["a","b","c"].join(" ") => "a b c"
["a","b","c"].join("-|-") => "a-|-b-|-c"

How do I capture the output of a pry shell command?

I'm using pry and I want to capture, and work with output of a shell command.
For example, If I run
pry(main)> .ls
I want to get the list of files into an array that I can work with in Ruby.
How can I do this?
This is a pretty old question but I'll answer it anyways. There are two primary methods of getting data out of pry commands. The first is if the command sets the keep_retval option to true, which the shell command does not. The second, is to use the virtual pipe. In your example this can be done as:
fizz = []
.ls | {|listing| fizz = listing.split("\n")} # can also be written as
.ls do |listing|
fizz = listing.split("\n")
end
I assume it's some kind of pry's magic ;-)
After quick look at what's happening (I didn't look at pry's source), you might want to use this:
`ls`.split("\n")
or
Dir['./*']
What's good about this solution is that it will work outside of pry

Resources