How to require Ruby 1.9 from a required file?

Is there any way to require Ruby 1.9 from a required file such that I
can trigger an error message before the main file is parsed?

Suppose I'm making a DSL that depends on the very nice Ruby 1.9 hash
syntax. Here's an example:

app.rb

    $LOAD_PATH << File.dirname(__FILE__)
    require 'my_library'

    make_pie apple:2, butter:1, flour:4
    puts "bye"

in my_library I want to report an error if we're not running with 1.9,
so I did this:

    if RUBY_VERSION < "1.9.0"
      abort <<-end_message
        This requires Ruby 1.9
      end_message
    end

    def make_pie options
      return unless options.respond_to? :key
      puts "with " + options.keys.join(',') + " we can make a great pie"
    end

It works great as long as I don't have Ruby 1.9 syntax in the main file,
but when I do, Ruby 1.8.7 will show that error first.

    $ rvm use 1.9.2-head
    Using ruby 1.9.2 head
    $ ruby app.rb
    with apple,butter,flour we can make a great pie
    bye
    $ rvm use 1.8.7
    Using ruby 1.8.7 p249
    $ ruby app.rb
    app.rb:4: syntax error, unexpected tINTEGER, expecting
tSTRING_CONTENT or tSTRING_DBEG or tSTRING_DVAR or tSTRING_END
    make_pie apple:2, butter:1, flour:4
                    ^

I posted the files at: http://github.com/ultrasaurus/ruby_version_check

Sure this can be solved with documentation OR changing the syntax of my
DSL to use 1.8.7, but I was hoping for a nicer solution for end users
(who are expected to be kids).

Thanks in advance,

Sarah

http://www.ultrasaurus.com
http://blazingcloud.net

···

--
Posted via http://www.ruby-forum.com/.

You can't catch a SyntaxError in same file in which it occurs (if you
think about it - your rescue statement has to come after the place
where the syntax error has already occurred). You ~can~ catch a
SyntaxError in eval'd or loaded code. So, instead of requiring your
library, why not use a script loader like this:

file: recipe-dsl

  #!/usr/bin/env ruby
  def make_pie(params)
    p params
  end

  begin
    load ARGV[0]
  rescue SyntaxError => e
    if RUBY_VERSION < '1.9.0'
      puts "You need ruby 1.9.x to run this script"
    else
      raise
    end
  end

which you use to run the DSL scripts like so:

  $ recipe-dsl ~/apple-pie.recipe

where apple-pie.recipe contains just your DSL statements:

file: apple-pie.recipe

  make_pie apple: 2, butter: 1, flour: 4

If you try to run this under 1.8.x, you'll get:

  $ ./recipe-dsl apple-pie.recipe
  You need ruby 1.9.x to run this script

If you really do have a syntax error in your recipe script, that will
be reported under 1.9.x.

HTH

Regards,
Sean

···

On Mon, Sep 6, 2010 at 9:40 PM, Sarah Allen <sarah@ultrasaurus.com> wrote:

Is there any way to require Ruby 1.9 from a required file such that I
can trigger an error message before the main file is parsed?

Suppose I'm making a DSL that depends on the very nice Ruby 1.9 hash
syntax. Here's an example:

app.rb

$LOAD_PATH << File.dirname(__FILE__)
require 'my_library'

make_pie apple:2, butter:1, flour:4
puts "bye"

in my_library I want to report an error if we're not running with 1.9,
so I did this:

if RUBY_VERSION < "1.9.0"
abort <<-end_message
This requires Ruby 1.9
end_message
end

def make_pie options
return unless options.respond_to? :key
puts "with " + options.keys.join(',') + " we can make a great pie"
end

It works great as long as I don't have Ruby 1.9 syntax in the main file,
but when I do, Ruby 1.8.7 will show that error first.

$ rvm use 1.9.2-head
Using ruby 1.9.2 head
$ ruby app.rb
with apple,butter,flour we can make a great pie
bye
$ rvm use 1.8.7
Using ruby 1.8.7 p249
$ ruby app.rb
app.rb:4: syntax error, unexpected tINTEGER, expecting
tSTRING_CONTENT or tSTRING_DBEG or tSTRING_DVAR or tSTRING_END
make_pie apple:2, butter:1, flour:4
^

I posted the files at: GitHub - ultrasaurus/ruby_version_check: understanding how to require Ruby 1.9

Sure this can be solved with documentation OR changing the syntax of my
DSL to use 1.8.7, but I was hoping for a nicer solution for end users
(who are expected to be kids).

Thanks in advance,

Sarah

Sarah Allen wrote:

Is there any way to require Ruby 1.9 from a required file such that I
can trigger an error message before the main file is parsed?

Suppose I'm making a DSL that depends on the very nice Ruby 1.9 hash
syntax. [...]

[...]

Sure this can be solved with documentation OR changing the syntax of my
DSL to use 1.8.7, but I was hoping for a nicer solution for end users
(who are expected to be kids).

Unfortunately, no.

Ruby 1.8.8 is supposed to be syntactically compatible with Ruby 1.9,
specifically to solve the very problem you are having. So, in Ruby
1.8.8, just *parsing* Ruby 1.9 code should not result in an error,
only actually *running* it. But obviously, Ruby 1.8.8 isn't out yet,
and if you could get the kids to upgrade to Ruby 1.8.8, you could
presumably get them to upgrade to Ruby 1.9.2 as well, so ...

jwm

Sean O'halpin wrote:

You can't catch a SyntaxError in same file in which it occurs (if you
think about it - your rescue statement has to come after the place
where the syntax error has already occurred). You ~can~ catch a
SyntaxError in eval'd or loaded code. So, instead of requiring your
library, why not use a script loader like this:

file: recipe-dsl

  #!/usr/bin/env ruby
  def make_pie(params)
    p params
  end

  begin
    load ARGV[0]
  rescue SyntaxError => e
    if RUBY_VERSION < '1.9.0'
      puts "You need ruby 1.9.x to run this script"
    else
      raise
    end
  end

Or:

my_library.rb:
  #!/usr/bin/env ruby
  abort "You need ruby 1.9.x to run this script" if RUBY_VERSION <
"1.9.0"
  load 'my_library_1.9'

if you know your libraries Ruby 1.9-dependencies aren't limited to
constructs that would be syntactic errors in Ruby 1.8, so you don't want
the error message to depend on the presence of syntax errors.

This generalizes to:

my_library.rb:
  #!/usr/bin/env ruby
  case
  when RUBY_VERSION >= "1.9.0" then load 'my_library_1.9'
  else load 'my_library_1.8'
  end

if you add an Ruby 1.8 implementation.

···

--
Posted via http://www.ruby-forum.com/\.