require in instance_eval

U

unexist

Hello list,

just wondered about following: http://pastie.org/1249746

Is this the intended behaviour of require? I am a bit surprised, that it evals the code on object-level
instead of staying in the scope of my Foobar object.

Is there a way around this? Also is it's possible to set the LOAD_PATH to get require_relative in
instance_eval to work? I know about the path parameter of instance_eval, but apparently it doesn't
change anything.

With best regards

Christoph
 
J

Jeremy Bopp

Hello list,

just wondered about following: http://pastie.org/1249746

Is this the intended behaviour of require? I am a bit surprised, that it evals the code on object-level
instead of staying in the scope of my Foobar object.

You can call require from anywhere, be it within a class definition, a
method, or even an eval statement. In all cases the general expectation
is that require loads the file into the global namespace rather than
into the scope of the calling code.
Is there a way around this?

Have you tried loading the contents of the file as a string and then
passing the string to eval rather than call require on the file? I
think that might do what you want.
Also is it's possible to set the LOAD_PATH to get require_relative in
instance_eval to work?

What exactly is the error message when you try to use require_relative?
I know about the path parameter of instance_eval, but apparently it doesn't
change anything.

Yeah, that is only to supply a file name to be reported as the source
file if there are problems that require a stack trace to be produced.
It's not intended to help you load a file at all.

-Jeremy
 
U

unexist

---- On Tue, 26 Oct 2010 18:35:58 +0200 Jeremy Bopp wrote ----
You can call require from anywhere, be it within a class definition, a
method, or even an eval statement. In all cases the general expectation
is that require loads the file into the global namespace rather than
into the scope of the calling code.

Yeah this makes sense, but it still surprised me. I thought it will require it in the
current scope. So for proper sandboxing you need to change require.
Have you tried loading the contents of the file as a string and then
passing the string to eval rather than call require on the file? I
think that might do what you want.

I am using ruby as embedded scripting language in my window manager and for
the config file. Recently I decided moving the DSL parts of the config into a kind of
sandbox for evaling and to avoid polluting the global namespace.

Some of the users splitted their config into several parts and included them with
require and require_relative.
What exactly is the error message when you try to use require_relative?

When I use the example from before and just change the require to
require_relative in read.rb I get this error:

read.rb:3:in `require_relative': cannot infer basepath (LoadError)
from read.rb:3:in `<main>'
from foobar.rb:11:in `instance_eval'
from foobar.rb:11:in `<main>'

Which probably makes sense, since the basepath is undefined, but it a pita. ;)

With best regards

Christoph
 
J

Jeremy Bopp

---- On Tue, 26 Oct 2010 18:35:58 +0200 Jeremy Bopp wrote ----


Yeah this makes sense, but it still surprised me. I thought it will require it in the
current scope. So for proper sandboxing you need to change require.

It would seem so, but you need to take care with that since your users
may still expect to use require to load other extensions.
I am using ruby as embedded scripting language in my window manager and for
the config file. Recently I decided moving the DSL parts of the config into a kind of
sandbox for evaling and to avoid polluting the global namespace.

Some of the users splitted their config into several parts and included them with
require and require_relative.

Maybe your DSL can provide an alternative to require that does what you
want while leaving require alone. It would break compatibility with
some existing configurations that use require and require_relative, but
you could have a deprecation period where using those methods would
produce a warning and then fall back to the DSL's alternative.
When I use the example from before and just change the require to
require_relative in read.rb I get this error:

read.rb:3:in `require_relative': cannot infer basepath (LoadError)
from read.rb:3:in `<main>'
from foobar.rb:11:in `instance_eval'
from foobar.rb:11:in `<main>'

Which probably makes sense, since the basepath is undefined, but it a pita. ;)

That makes sense, and now I see that this is where you meant that adding
a file path argument to instance_eval didn't help. You were hoping that
doing so would give require_relative a basepath from which to start
searching.

I wonder if the inability to use require_relative from within an eval
should be considered a bug. Maybe require_relative should support an
argument for an explicit basepath, at least as a workaround.

-Jeremy
 
U

unexist

---- On Tue, 26 Oct 2010 23:06:40 +0200 Jeremy Bopp wrote ----
It would seem so, but you need to take care with that since your users
may still expect to use require to load other extensions.

Yep true, the point is I never encouraged users to use this, I don't even use it
myself and now I need to face them with this kind of regress in their opinion.
Maybe your DSL can provide an alternative to require that does what you
want while leaving require alone. It would break compatibility with
some existing configurations that use require and require_relative, but
you could have a deprecation period where using those methods would
produce a warning and then fall back to the DSL's alternative.

Hm good I idea, I will think about it. Most likely I will just keep it as is, because
the DSL is that easy breaking it apart has almost no benefits.
I wonder if the inability to use require_relative from within an eval
should be considered a bug. Maybe require_relative should support an
argument for an explicit basepath, at least as a workaround.

Either that or a way to set the basepath directly in this cases. *eval should
be aware where the stuff came from. The current "(eval)" is probably a good
default for meaningful error messages.

With best regards

Christoph
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top