From: Brian Candler Date: 2003-05-04T01:29:49+09:00 Subject: Re: [Q] eval and binding with mod_ruby On Fri, May 02, 2003 at 07:43:42AM +0900, kwatch wrote: > view.rhtml > .-------------------- > Hello <%= username %>! > .-------------------- > > logic.rbx > .-------------------- > require 'cgi' > cgi = CGI.new > print cgi.header > > require 'eruby' > username = 'Ruby' > ERuby::import('view.rhtml') # no binding(), but evaled with no error. > .-------------------- > > I have read ERuby source code (eruby_load() in eruby_lib.c), > but I could not get understand how ERuby do. > > Would you teach me if you know it? I don't :-) But I have just installed eruby now... I've played with this a bit and have been unable to make the local variable 'username' available in viewloader.rb without passing a binding explicitly as you did - having tried various combinations of instance_eval, passing in 'self' as a parameter etc. The usual rule is that when you call a method, a new scope is started (so local variables in the calling method are not visible in the called method). I don't understand how or why ERuby::import is able to see them when it calls 'eval'. The relevant function in eruby_lib.c looks like static VALUE eruby_import(VALUE self, VALUE filename) { VALUE compiler, file, code; compiler = eruby_compiler_new(); file = rb_file_open(STR2CSTR(filename), "r"); code = eruby_compiler_compile_file(compiler, file); rb_funcall(ruby_top_self, rb_intern("eval"), 3, code, Qnil, filename); return Qnil; } And the closest I can get to simulate that is: ----------------------------------- TOP_SELF = self module Foo def Foo.output(code) TOP_SELF.send( :eval, code ) end end username="test" Foo.output("puts username") ----------------------------------- but this doesn't work :-( Anybody else got any better ideas, or an explanation of why ERuby doesn't need you to pass in an explicit 'binding'? Thanks, Brian.