1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
#! /usr/bin/env perl
use strict;
use File::Spec;
my $code;
BEGIN {
my @spec = File::Spec->splitpath(__FILE__);
$spec[2] = 'RubyXGettext.rb';
my $filename = File::Spec->catpath(@spec);
open HANDLE, "<$filename"
or die "Cannot open '$filename': $!\n";
$code = join '', <HANDLE>;
}
use Inline Ruby => $code;
# First inject all methods from the Ruby class into Perl.
my %ruby_methods = %RubyXGettext::;
foreach my $key (sort keys %ruby_methods) {
no strict 'refs';
if ('new' ne $key && defined &{"RubyXGettext::$key"}) {
*{"Locale::XGettext::Ruby::$key"} = sub {
my ($self, @args) = @_;
$self->{__helper}->$key(@args);
};
}
}
# Ruby does not support calling arbitrary Perl methods or subroutines.
# But we can pass a closure as a Proc that can be called from Ruby.
# This is not a general-purpose solution but works in our case.
my @isa = @Locale::XGettext::Ruby::ISA;
my %seen;
foreach my $class (@isa, 'Locale::XGettext::Ruby') {
no strict 'refs';
foreach my $method (keys %{$class . '::'}) {
# Do not export what we had imported above.
next if $ruby_methods{$method};
# And private methods.
next if $method =~ /^__/;
# And more stuff.
next if $method =~ /::$/;
next if 'new' eq $method;
next if 'newFromArgv' eq $method;
next if 'ISA' eq $method;
next if $seen{$method}++;
Inline::Ruby::rb_eval(<<EOF);
class RubyXGettext
def $method(*args)
\@xgettext['$method'].call(*args)
end
end
EOF
}
}
Locale::XGettext::Ruby->newFromArgv(\@ARGV)->run->output;
package Locale::XGettext::Ruby;
use strict;
use base qw(Locale::XGettext);
sub newFromArgv {
my ($class, @args) = @_;
my $self = bless {}, $class;
my %procs;
foreach my $method (keys %seen) {
$procs{$method} = sub {
$self->$method(@_);
}
}
$self->{__helper} = RubyXGettext->new(\%procs);
$self->SUPER::newFromArgv(@args);
return $self;
}
|