What are the benefits of using FileUtils methods http://ruby-doc.org/core/classes/FileUtils.html than the equivalent Bash commands?
Over and above the fact that you don't have to worry about ensuring your target platform has the specific tools you're using installed, and over and above the problem of doing proper quoting of shell oddities (especially problematical if you target both Windows and Unix-alikes -- Cygwin, GNUWin32, etc. notwithstanding), if you use Ruby's FileUtils you have the moderately-sized overhead of a Ruby function call while if you use external utilities you have the rather sizable overhead of firing up an external process each and every "call".
The FileUtils methods work on Windows.
They are easier to call from inside Ruby scripts because they accept Ruby objects as arguments. This means that you don't have to handle escaping and what not every time you call them.
when you farm stuff out to the shell, you are adding a dependency on those apps. FileUtils is pure ruby, so it works (and works the same, more or less) anywhere that ruby works.
Works across multiple platforms
Does not spawn a new process to issue the command (so it consumes less resources)
I would not say there is no benefits in using Ruby's FileUtils, since you can use them anywhere you have Ruby( especially if your task is in web development). But that does not mean you can't use those shell tools in other platforms as well. Yes, you can write your scripts in *nix shell, and you can run them as well with little or no modification in, say, Windows using cygwin or GNU win32.(and others).
In terms of benefits of Ruby's FileUtils against shell's, its only minimal, since what you can do with FileUtils you can do also with shell's.
Related
TL;DR: Whats the most optimal way to write portable general-purpose automation scripts for Windows, Mac and Linux?
Longer version:
I work with different platforms and often write shell scripts to automate things (run programs and other scripts, manipulate files and directories, etc).
The problem is that sh/bash substitutes on Windows are tricky, complex, often incompatible or lack some native unix tools. And cygwin scares a regular user, in case when I share some of my scripts with the others.
I find that .bat is very limited and ugly. And I didn't use Powershell a lot, but it looks a bit overcomplicated to me (or should I just give it another try?).
What would you recommend to do in such case? Have you had similar challenges, how did you solve them?
I would advice you use some configuration manager as Ansible, Puppet or Chef. Since their sole purpose is to automate things, and some of them are cross platform. Google each one I mentioned, scripts are generally easy to write in them and they will work on all the platforms, but you will need to install the manager itself on each platform, which can be achieved with init.sh or with a simple powershell script.
Confused a little on ruby. I know it makes .rb files, but does it make exe or com files or is it just used as as web application?
I know a bit writing the code, but what to do with the files after.
the question is a bit too broad.
you have to step back and look at how source code in general ends up being executed (i.e. it is used).
In case of some programming languages (e.g. C/C++) it's compiled to a native form and can be executed directly afterwards;
In case of other languages it's compiled to an intermediate form (e.g. Java/C#) and executed by a vm (jvm/clr)
In case of yet other languages is interpreted at runtime (e.g. Ruby/Python).
So in the specific case of Ruby, you have the interpreter that loads the rb files and runs them. This can be in the context of standalone apps or in th e context of a web server, but you almost always have the interpreter making sense of the ruby files. you don't get an executable the same way as the you get for languages that are compiled to machine code.
Normally you just run the .rb file in the shell or command prompt. For example in the windows command prompt:
C:\path\> ruby filename.rb
This will execute the filename.rb file from the command prompt.
If you need to run a ruby program on a computer without a ruby installation there are a few options out there.
Try this website:
https://www.ruby-toolbox.com/categories/packaging_to_executables
I personally have used OCRA to pass a program to relatives who are less computer literate. It was pretty straight forward,I haven't tried the other tools.
Good luck,
I am running within a Ruby script (a Vagrantfile, specifically) and I want to invoke another ruby executable (berks installed against system ruby, specifically). I know I can do something like
PATH=/usr/bin GEM_PATH=/var/lib/ruby/1.9.1 berks ...
But, that's not very portable. (Different machines will need different GEM_PATH, for instance). So, how can I invoke a script installed against a different Ruby environment from within a Ruby script?
Well, the task at hand sounds not-very-portable, since its entire reason for being is a system-specific quirk of different Rubies being installed in different places. Not all systems will even have those specific Ruby versions.
It sounds to me like your best bet would probably be to allow the user to set certain environment variables (I dunno, $BERKS_SUBRUBY_PATH or something) and use those if they are set. That way anyone who needs to use the workaround has an easy way to do so, but you're not forcing everybody to have the same system config.
What are the major differences between the execution of Ruby C bindings vs. Ruby wrapper for system calls?
To my question into context, I am looking into incorporating Git version control functionality heavily into a Ruby on Rails application. In approaching this task I do not understand the how to think about the execution pipeline of a Ruby program which incorporates a library implemented with Ruby C bindings such as yajl-ruby vs. a Ruby wrapper for system calls such as the git Ruby Gem.
Bindings interface directly with the library's API, while wrappers use system calls to invoke the end-user application from the command line.
Wrappers are similar to UNIX pipes – programs have no knowledge about each other's internals and communicate through a textual interface. Loose coupling comes with a price, though. System calls are expensive operations and will dramatically slow down your application.
This is why bindings are great. Since they use the library's programming interface, the overhead is significantly reduced. GitHub had its own git wrapper, and speed was issue that led them to implement git in Ruby.
They did it themselves because it is kind of hard to make bindings for git. It wasn't designed to be used as a library. It's really awkward to call its functions directly since it calls die() on pretty much any error.
The demand for a proper git library led to the development of libgit2. It even comes with Ruby bindings! Since you want to integrate git functionality with your application, you should check it out.
So ruby 1.9 is really nice in that it'll automatically require rubygems, and hence when you call require 'somegem' without first requiring rubygems it'll work, and that's generally awesome.
But I have a ton of shell scripts using ruby, and they generally don't rely on rubygems. Shell tools should run instantly, and loading rubygems for nothing is a major drag, mostly because it involves a bunch of disk operations with scattered small files.
I want to be able to tell ruby, when running these shell scripts, to skip loading gems. Ideally, something like #!ruby --no-rubygems in the shebang line.
Is there such a thing? Or maybe a compile option that'll tell ruby rubygems must be required manually?
Yes, you can use the --disable-gems option.
Note that whether or not passing options in the shebang line works depends on your operating system. Some operating systems don't support passing options at all, some only support passing one option or argument.
So, if you have for example
#!/usr/bin/env ruby
Then it's pretty unlikely that you will be able to attach the option to the end. If OTOH you change that to
#!/usr/local/bin/ruby --disable-gems
Then you have hardwired the location of the Ruby binary into your script.
And of course there are operating systems that don't interpret shebang lines at all. (After all, they were never specified in any standard, and aren't even properly documented.)
An alternative would be to set the RUBYOPT environment variable in your shell environment and simply switch to a different environment with RUBYOPT unset (or set to -w, my personal favorite) for your Ruby development.