Forum: Ruby Format of RUBYOPT

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.
4b174722d1b1a4bbd9672e1ab50c30a9?d=identicon&s=25 Ryan Leavengood (Guest)
on 2006-04-25 03:24
(Received via mailing list)
Hello all,

I'm working on fixing the remaining installer problems in the
One-Click Installer so we can finally release it, and one of those
involves the manipulation of the RUBYOPT environment variable. On that
note, I was wondering the format of that. If there are multiple
entrys, how are they formatted? Just spaces in between?

In other words, if I am to add rubygems as a new option while
preserving the older options, what would I do? Just add it with a
space prefix at the end of RUBYOPT?

In my testing there seemed to be cases when RUBYOPT was not read and I
also got errors sometimes, so I want to ensure I don't break someone's
system by setting an invalid RUBYOPT.

Thanks,
Ryan
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 unknown (Guest)
on 2006-04-25 04:10
(Received via mailing list)
On Tue, 25 Apr 2006, Ryan Leavengood wrote:

> space prefix at the end of RUBYOPT?
>
> In my testing there seemed to be cases when RUBYOPT was not read and I
> also got errors sometimes, so I want to ensure I don't break someone's
> system by setting an invalid RUBYOPT.
>
> Thanks,
> Ryan

if you look in ruby.c you'll see that it's literally parsed as part of
the
commandline - except only the switchs 'IdvwrK' and 'T' are accepted.  it
looks
like it is indeed space separated.

   harp:~ > cat rubylib/a.rb
   A=42

   harp:~ > RUBYOPT="-ryaml -Irubylib/ -ra" ruby -e "p [YAML, A]"
   [YAML, 42]

seems to work.

cheers.

-a
4b174722d1b1a4bbd9672e1ab50c30a9?d=identicon&s=25 Ryan Leavengood (Guest)
on 2006-04-25 04:13
(Received via mailing list)
On 4/24/06, Ryan Leavengood <leavengood@gmail.com> wrote:
>
> In other words, if I am to add rubygems as a new option while
> preserving the older options, what would I do? Just add it with a
> space prefix at the end of RUBYOPT?

Responding to my own thread: Given that the above is true, I wrote
Ruby script to work out the logic of this and here is the result:

$already_defined = {}

def add_to_rubyopt(var, rubyopt)
  a = rubyopt.split(' ')
  if not a.include?(var)
    a << var
    $already_defined[var] = nil
  else
    $already_defined[var] = true
  end
  a.join(' ')
end

def del_from_rubyopt(var, rubyopt)
  if not $already_defined[var]
    a = rubyopt.split(' ')
    a.delete(var)
    a.join(' ')
  else
    rubyopt
  end
end

require 'test/unit'

class RubyOptTest < Test::Unit::TestCase
  def test_add_to_rubyopt
    var = 'rubygems'
    # Before and after tests
    [
      ['', var],
      ['w', "w #{var}"],
      ['w v somethinglong', "w v somethinglong #{var}"]
    ].each do |before, after|
      assert_equal(after, add_to_rubyopt(var, before))
      assert_equal(before, del_from_rubyopt(var, after))
    end
    # Here nothing should be changed
    [var, "w #{var}", "w v #{var} somethinglong"].each do |s|
      assert_equal(s, add_to_rubyopt(var, s))
      assert_equal(s, del_from_rubyopt(var, s))
    end
  end
end
__END__

If the logic of the above seems wrong in any way, let me know. Now the
trick is writing the above in the NSIS scripting language (it's
practically like assembler compared to Ruby, grrr.)

Ryan
4b174722d1b1a4bbd9672e1ab50c30a9?d=identicon&s=25 Ryan Leavengood (Guest)
on 2006-04-25 04:19
(Received via mailing list)
On 4/24/06, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:
>
> seems to work.

Hmmm, OK. Then why does setting RUBYOPT to just rubygems work (it has
no dash?) That doesn't work on the command-line (at least on Windows):

C:\_Ryan\ruby_installer\svn\NSIS>ruby rubygems -e 'puts "hello"'
ruby: No such file or directory -- rubygems (LoadError)

C:\_Ryan\ruby_installer\svn\NSIS>ruby -rubygems -e 'puts "hello"'
hello

Maybe to be safe I should always just add -rubygems (i.e with a dash
prefix.)

Ryan
C475cffda1800fbc3f3af17bc10c220f?d=identicon&s=25 Curt Hibbs (Guest)
on 2006-04-25 04:25
(Received via mailing list)
On 4/24/06, Ryan Leavengood <leavengood@gmail.com> wrote:
> >    A=42
> ruby: No such file or directory -- rubygems (LoadError)
>
> C:\_Ryan\ruby_installer\svn\NSIS>ruby -rubygems -e 'puts "hello"'
> hello
>
> Maybe to be safe I should always just add -rubygems (i.e with a dash
> prefix.)
>
> Ryan


I only recently discovered this myself... with a single option you can
omit
the "-", but with multiple, the "-" is required.

Curt
4b174722d1b1a4bbd9672e1ab50c30a9?d=identicon&s=25 Ryan Leavengood (Guest)
on 2006-04-25 04:32
(Received via mailing list)
On 4/24/06, Curt Hibbs <ml.chibbs@gmail.com> wrote:
>
> I only recently discovered this myself... with a single option you can omit
> the "-", but with multiple, the "-" is required.

OK, so not only do I need to check for an existing RUBYOPT, but if is
defined and it only has one option, I need to add a dash to the
existing if it lacks it, then add -rubygems. Then on uninstall this
needs to be restored. Nice. I'm glad I'm prototyping this in Ruby.

Ryan
4b174722d1b1a4bbd9672e1ab50c30a9?d=identicon&s=25 Ryan Leavengood (Guest)
on 2006-04-25 04:53
(Received via mailing list)
On 4/24/06, Ryan Leavengood <leavengood@gmail.com> wrote:
>
> OK, so not only do I need to check for an existing RUBYOPT, but if is
> defined and it only has one option, I need to add a dash to the
> existing if it lacks it, then add -rubygems. Then on uninstall this
> needs to be restored. Nice. I'm glad I'm prototyping this in Ruby.

And here is the modified test:

$old_value = {}

def add_to_env(add_this, env_var_name, env_var_value, split_char=' ')
  result = env_var_value
  a = env_var_value.split(split_char)
  if not (a.include?(add_this) or a.include?("-#{add_this}"))
    $old_value[env_var_name] = env_var_value
    if a.length == 1 and a[0][0].chr != '-'
      a[0] = '-' + a[0]
    end
    a << "-#{add_this}"
    result = a.join(split_char)
  end
  result
end

def restore_env(env_var_name, env_var_value)
  if $old_value[env_var_name]
    result = $old_value[env_var_name]
    $old_value[env_var_name] = nil
    result
  else
    env_var_value
  end
end

require 'test/unit'

class RubyOptTest < Test::Unit::TestCase
  def test_add_to_rubyopt
    to_add = 'rubygems'
    env_var = 'RUBYOPT'
    # Before and after tests
    [
      ['', "-#{to_add}"],
      ['w', "-w -#{to_add}"],
      ['-w -v -somethinglong', "-w -v -somethinglong -#{to_add}"]
    ].each do |before, after|
      assert_equal(after, add_to_env(to_add, env_var, before))
      assert_equal(before, restore_env(env_var, after))
    end
    # Here nothing should be changed
    [to_add, "-w -#{to_add}", "-w -v -#{to_add} -somethinglong"].each do
|s|
      assert_equal(s, add_to_env(to_add, env_var, s))
      assert_equal(s, restore_env(env_var, s))
    end
  end
end
__END__

Again if anything looks wrong let me know :)

Ryan
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 unknown (Guest)
on 2006-04-25 05:08
(Received via mailing list)
On Tue, 25 Apr 2006, Ryan Leavengood wrote:

>>    [YAML, 42]
> hello
>
> Maybe to be safe I should always just add -rubygems (i.e with a dash prefix.)

ruby.c, in proc_options:


     731     if (rb_safe_level() == 0 && (s = getenv("RUBYOPT"))) {
     732         while (ISSPACE(*s)) s++;
     733         if (*s == 'T' || (*s == '-' && *(s+1) == 'T')) {
     734             int numlen;
     735             int v = 1;
     736
     737             if (*s != 'T') ++s;
     738             if (*++s) {
     739                 v = scan_oct(s, 2, &numlen);
     740                 if (numlen == 0) v = 1;
     741             }
     742             rb_set_safe_level(v);
     743         }


in the else block we eat the dash and any space, iff present.  then we
look
for the opt char


     744         else {
     745             while (s && *s) {
     746                 if (*s == '-') {
     747                     s++;
     748                     if (ISSPACE(*s)) {
     749                         do {s++;} while (ISSPACE(*s));
     750                         continue;
     751                     }
     752                 }
     753                 if (!*s) break;
     754                 if (!strchr("IdvwrK", *s))
     755                     rb_raise(rb_eRuntimeError, "illegal switch
in RUBYOPT: -%c", *s);


now, given RUBYOPT=-rubygems, and *s==r, we call moreswitches


     756                 s = moreswitches(s);
     757             }
     758         }
     759     }


so in this function


     433 static char*
     434 moreswitches(s)
     435     char *s;
     436 {
     437     int argc; char *argv[3];
     438     char *p = s;
     439
     440     argc = 2; argv[0] = argv[2] = 0;
     441     while (*s && !ISSPACE(*s))
     442         s++;
     443     argv[1] = ALLOCA_N(char, s-p+2);
     444     argv[1][0] = '-';
     445     strncpy(argv[1]+1, p, s-p);
     446     argv[1][s-p+1] = '\0';
     447     proc_options(argc, argv);
     448     while (*s && ISSPACE(*s))
     449         s++;
     450     return s;
     451 }


we eat whitespace, setup argv=[0, "-rubygems", 0] and argc == 2.  then
recurse
into proc_options (the first method shown).


so, as far as i can tell (and i've had three beers), proc_options finds
the
'r', jumps into moreswitches which restores the '-', and the were back
into
proc_options with '-rubygems', which works because of the 'ubygems'
hack.  the
parsing of RUBYOPT looks as if it ignores '-' or lack thereof be design,
but i
certainly can't be knowing.

good luck!  ;-)

-a
25e11a00a89683f7e01e425a1a6e305c?d=identicon&s=25 Wilson Bilkovich (Guest)
on 2006-04-25 05:33
(Received via mailing list)
On 4/24/06, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:
> >>
> >
>      733         if (*s == 'T' || (*s == '-' && *(s+1) == 'T')) {
>
>      749                         do {s++;} while (ISSPACE(*s));
>
>      434 moreswitches(s)
>      445     strncpy(argv[1]+1, p, s-p);
>
> --
To summarize, if you're going to alter RUBYOPT by appending something,
you should append a space and then '-rrubygems', to be sure?
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 unknown (Guest)
on 2006-04-25 05:42
(Received via mailing list)
On Tue, 25 Apr 2006, Wilson Bilkovich wrote:

> To summarize, if you're going to alter RUBYOPT by appending something, you
> should append a space and then '-rrubygems', to be sure?

it looks that way to me.  but caveat emptor.

-a
This topic is locked and can not be replied to.