Forum: JRuby rescue error?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
F4c2dcb24f2828cde331ba6a2c9ea10d?d=identicon&s=25 Jabari Z. (jabari_z)
on 2015-03-21 05:45
I'm creating a gem and have been testing it on MRI, JRuby, and Rubinius.

I have a section of code which checks to see if the Linux/Unix cli
command 'factor' exists on the platform the gem is installed on.  If it
exists I wrap some ruby around it and use it. If 'factor' doesn't exists
then I create pure ruby versions of the same methods.

To do this, I invoke the 'factor' command. If it exists I create the
methods I want using it. If it doesn't exists, an error is thrown which
I use a 'rescue' section to resolve to create pure ruby versions.

Below is code to show the use of 'rescue':

If the system is a RUBY_PlATFORM which has 'factor' (Linux/Unix)

then the line:  `factor 10`.split(' ') != []

will be performed with no error, and the code will proceed in sequence.

If the system doesn't have 'factor' a sys error is thrown and 'rescued'.

I test this on my Linux system by running it with the correct spelling
of 'factor', which outputs 'OS versions'.

I then create a false cli command 'factorz' and run the code, and for
MRI (2.2.1 and 2.1.2) and Rubinius (2.5.2) a sys error is thrown and the
'rescue' section is invoked correctly and 'Ruby versions' is shown.

However, on JRuby 1.7.19, in both cases I get 'OS versions'.

So apparently, JRuby isn't throwing a system error when it attempts to
run a non-existent cli command, which doesn't conform to MRI (2.2; 2.1).

1)Is this a bug in JRuby, or is this allowed behavior?

2)Is there a 'better' more universally transferable way to do this?


  begin

    # Test Operating Systems if *nix cli command 'factor' exists

    `factor 10`.split(' ') != []
    #`factorz 10'.split(' ') != []  # mimic nonexistent on system

    # code would go here to create 'factor' coded methods

    puts 'OS versions'

  rescue # if 'factor' not in system use pure ruby versions

    # code would go here to create pure ruby coded methods

    puts 'Ruby versions'

  end
486ca04f06d968004643ce5b47376ded?d=identicon&s=25 Keith B. (keith_b)
on 2015-03-21 06:37
(Received via mailing list)
If you don’t want to do the test on Windows, then I believe you can rely
on the existence of the 'which' command.  In that case:

system(‘which factor’)

…will return true if it’s available, and false if it’s not.  This is
from my Mac, which does not have factor:

2.1.2 :003 > system('which ls')
/bin/ls
 => true
2.1.2 :004 > system('which factor')
 => false

Of course, this does not guarantee that the ‘factor’ executable found is
the one you want.

You could do something like this:

def factor_available?
  RUBY_PLATFORM != ‘mswin’ && system(‘which factor’)
end

You might need to tweak the platform test; there are other values of
RUBY_PLATFORM that are Windows, but some of them (e.g. ‘cygwin’, and
maybe ‘mingw’?) simulate Unix so may not need to be excluded.

- Keith
F4c2dcb24f2828cde331ba6a2c9ea10d?d=identicon&s=25 Jabari Z. (jabari_z)
on 2015-03-21 17:13
Hey Keith, thanks.

Doing something like this:

if system('which factor'); puts 'Yes factor' else 'No factor' end

is much cleaner and transportable.

I tested it on my system with MIR (1.8.7, 2.1.2, 2.2.1), JRuby-1.7.19
and Rubinius-2.5.2, and there were no problems. I'll try it later on my
Win7 system with Rubyinstaller rubies.

FYI, I started out using the RUBY_PLATFORM value to check against, but
soon realized I would have to know if 'factor' runs on all the possible
ruby platforms to make if universally transportable, so I started
checking directly for 'factor' being on a platform. In Unix 'factor' has
been standard since 1974, and in Linux and BSD since their inception, so
I'm not too concerned about possible false positives on other platforms.

https://en.wikipedia.org/wiki/Factor_(Unix)

The still open question, though, is JRuby's non-conformist to MRI
behavior handling rescue in the original example. This can obviously
have catastrophic consequences for people expecting their MRI code to
operate the same on JRuby.
58c538d6f6e8fbf54779c5607e567bff?d=identicon&s=25 John B. (john_b)
on 2015-03-21 19:03
(Received via mailing list)
open4 (gem on mri, native on jruby) will raise an error if it doesn't
find
the executable. try something like this:

if IO.respond_to?(:popen4) #jruby
  def open4(*args)
    IO.popen4(*args)
  end
else # mri
  require 'open4'
end

begin
  open4("monkey")
rescue
  print "monkey not available"
end
This topic is locked and can not be replied to.