Accessing Perl functions from Ruby

Hi Guys,

Please can you explain how to pass variables from ruby into perl
functions and to return the results back into ruby.

Kind Regards, Ap

There are several ways, and it depends on what you find convenient on
your platform:

  • Using files for storing input/output data
  • Using a named pipe
  • Using sockets

Thank you Ronald. Is there a way to do this within ruby itself?

Can you be more precise, what you mean by “within ruby”? You have a Ruby
process, and a Perl process, and they need to exchange data somehow,
isn’t it?

Thank you Ronald. Is there a way to do this within ruby itself?

I don’t think you can access the perl environment from within ruby
itself.

The best control you usually can have is via open/popen but that does
not allow you to easily tap into foreign functions directly.

Perhaps you may be able to use FFI/Fiddle/Dl or similar, or have a
virtual machine that would run perl similar to the jvm, but I have not
seen any project that really would pursue this.

Most people who use ruby end up sticking to ruby.

And if you it is a gem that you need from perl, let us know here -
either we may be able to find another one, or perhaps someone may port
that perl code to ruby. :smiley:

Robert H. wrote in post #1180183:

Thank you Ronald. Is there a way to do this within ruby itself?

I don’t think you can access the perl environment from within ruby
itself.
Perhaps you may be able to use FFI/Fiddle/Dl or similar, or have a
virtual machine that would run perl similar to the jvm, but I have not
seen any project that really would pursue this.

At least nothing which is close to complete, but if Ap is brave enough,
he might try:

One possibility would be to use the parrot VM (http://parrot.org/),
where you have Perl, but the Ruby implementation called “cardinal” is
still under development and I don’t know how stable the lastet version
is: GitHub - parrot/cardinal: Ruby on Parrot

Another possibility would be to use the Java VM. The Ruby implementation
is excellent (http://jruby.org) and prefered by some over the
“traditional” Ruby, but I don’t know about the completeness of the Perl
integration to Java: http://bsfperl.sourceforge.net/

Ronald

If I understand you right, you want to pass the parameters via the Perl
@ARGV array. This is fine, if the data to be transmitted to the Perl
size can be easily stringized and is not so huge as to break some system
limitations … This was not clear from your original posting.

Now to your code:

(1) Are you sure, exec is the right tool for this? This function causes
the current process to be replaced by the called one. If this is what
you want to do, fine. Otherwise, use the ‘system’ method instead:

(2) You are trying to build a single command string, which will then
look like

“/usr/bin/perl findRestrictionSites.pl --genome_version=hg38 …”

This can be fine, but depending on the data you are passing to the
program, you might or might not run into two problems:

  • Since the semantics of ‘system’ is, that the shell is invoked, which
    then in turn calls the Perl program (even though Ruby tries to “optimize
    away” the interim shell process), if your string contains some character
    with a special meaning to the shell (for instance, a $-sign), the shell
    would then act on these characters and, for instance, does a shell
    variable replacement. I’m not sure if you want this happen.

  • If the parameters, which you generate, contain spaces, these will be
    interpreted as “word separators”, i.e. one parameter will be interpreted
    as being two parameters, and this will upset GetOptions on the Perl
    side.

If you look at the link I have provided, ‘system’ also accepts as an
alternative a list of strings. Hence, instead of doing something like

system(‘/usr/bin/perl findRestrictionSites.pl --genome_version=hg38
…’)

you would better use the format

system(‘/usr/bin/perl’, ‘findRestrictionSites.pl’,
‘–genome_version=hg38’, …)

However, you don’t know the actualy parameters until runtime (because
they are supposed to be “calculated” dynamically). As a solution, you
use an array:

perl_command=[‘/usr/bin/perl’, ‘-w’,‘findRestrictionSites.pl’]

Into this array, you push the parameters one by one. For example,

perl_command << "–genome_version=#{chromo2.genome_version}

When you are done, you use Ruby’s “splice operator” (*) to turn this
array into a parameter list:

system(*perl_command)

Don’t forget to check the return value of ‘system’.

If your logic makes ‘exec’ more sensible, the same approach can also be
used with ‘exec’.

Thank you both for the advice. Here’s an example of the type of code I
want to run, just in case you can see an obvious fix. If I execute perl
and pass parameters from Ruby it would be helpful initially.

Kind Regards, Ap

class Test_Class

attr_reader :genome_version, :chromosome_name, :restriction_enzyme_seq

def initialize(genome_version, chromosome_name,
restriction_enzyme_seq)
@genome_version = genome_version
@chromosome_name = chromosome_name
@restriction_enzyme_seq = restriction_enzyme_seq
end

end

require_relative ‘Test_Class’

chromo2 = Test_Class.new(“genome version”, “chromosome 2”,“EcoR1”)

puts chromo2.genome_version
puts chromo2.chromosome_name
puts chromo2.restriction_enzyme_seq

this is where I need assistance is there a ruby methodology that will

enable me to execute perl with parameters mapped from Ruby

script = ‘findRestrictionSites.pl’
exec("/usr/bin/perl #{script @genome_version = genome_version,
@chromosome_name @restriction_enzyme_seq}")

findRestrictionSites.pl

#!/usr/bin/perl -w

use strict;
use Data::Dumper;
use Getopt::Long;

my $genome_version = ‘’;
my $chromosome = ‘’;
my $re_site = ‘’;

GetOptions (‘genome_version=s’=>$genome_version,
‘chromosome=s’=>$chromosome, ‘re_site=s’=>$re_site);
unless ($genome_version && $chromosome && $re_site){
print “\n\nUsage:\nfindRestrictionSites.pl --genome_version=hg38
–chromosome=22 --re_site=GAATTC\n\n”;
exit();
}

etc…