Right now we just use java's local variable to represent a ruby local
variable. So the following code in ruby:
a = 1
becomes this in java:
class XXX extends RubyProgram {
RubyValue run (...) {
RubyValue a = ObjectFactory.fixnum1;
}
}
But by doing this we can not get any information about java's local
variable, actually they are nameless in the compiled code.
So I am considering representing ruby local variable with java's public
field. So the above program will be compiled into:
class XXX extends RubyProgram {
public RubyValue a;
RubyValue run (...) {
a = ObjectFactory.fixnum1;
}
}
If we do this, Kernel#local_variables can be implemented with reflection.
It will take me a few days to finish this change and may not even work out.
Please let me know if you have better ideas.
_________________________________________________________________
Picture this – share your photos and you could win big!
http://www.GETREALPhotoContest.com?ocid=TXT_TAGHM&loc=us
> Picture this - share your photos and you could win big!
> http://www.GETREALPhotoContest.com?ocid=TXT_TAGHM&loc=us
>
>
> >
>
--
Best Regards
XRuby http://xruby.com
femto http://hi.baidu.com/femto
class Scope {
ArrayList local_vars = new ArrayList();
RubyValue getLocalVar(String name);
void setLocalVar(String name, RubyValue value);
}
I think jruby does this, but all local variable access will become java
method call. I am not sure how much performance penalty there will be. And
whatever we use are just internal details, user won't care much about it.
Right now I will try to use 'field' first, if it does not work out well,
will try Scope class later.
>From: "femto gary" <femt...@gmail.com>
>Reply-To: xruby...@googlegroups.com
>To: xruby...@googlegroups.com
>Subject: [xruby-devel] Re: Implementing Kernel#local_variables
>Date: Mon, 11 Jun 2007 22:21:12 +0800
>
>
>I remeber that from jruby's post, they say that Java's stack
>lacks many info where c ruby's stack needs,
>I think the best stragety here will be trying to implement
>kind of our stack infomation, like in SICP's ch4/ch5.
> using public/reflection is not a good idea, it's ugly,
>and I think it won't help implementing Binding, caller etc.
_________________________________________________________________
Like puzzles? Play free games & earn great prizes. Play Clink now.
http://club.live.com/clink.aspx?icid=clink_hotmailtextlink2
On Jun 11, 10:37 pm, "Xue Yong Zhi" <zhixuey...@hotmail.com> wrote:
> An alternative is to have a Scope class(or call it LocalVarManager):
>
> class Scope {
> ArrayList local_vars = new ArrayList();
>
> RubyValue getLocalVar(String name);
> void setLocalVar(String name, RubyValue value);
>
> }
>
> I think jruby does this, but all local variable access will become java
> method call. I am not sure how much performance penalty there will be. And
> whatever we use are just internal details, user won't care much about it.
>
> Right now I will try to use 'field' first, if it does not work out well,
> will try Scope class later.
>
#define POP_FRAME() \
ruby_current_node = _frame.node; \
ruby_frame = _frame.prev; \
} while (0)
so c ruby also handle's frame its own way.
The MRI story is a little bit more complicated than that. Frame
information doesn't have anything to do with local variables. MRI uses a
scope for that. A scope also have static scope information in something
called an ivtbl, which the parser sets up. The difference is that the
ivtbl contains the names of local variables for that static scope, and a
scope is a new instance of struct containing values for the same static
scope.
The problem for blocks for example, is that they need to close around
the outer scopes (so scopes need to have parents), but they also need
the frame information where they were created, since the frame contains
the current method name, the current self and other details like that.
I'm sorry to say that Rails uses local variables and closures like this
extensively, also bindings. Some of the more strange block behavior seen
in much Ruby code also depends on this being really right.
I'm currently trying to refactor JRuby's Scope and Frame structures, but
it's quite hard since they information is so involved.
Cheers
Ola Bini
--
Ola Bini (http://ola-bini.blogspot.com)
JRuby Core Developer
Developer, ThoughtWorks Studios (http://studios.thoughtworks.com)
"Yields falsehood when quined" yields falsehood when quined.
public RubyArray getLocalVars() {
return new RubyArray(new RubyString("a"), ...);
}
}
Because we know all local variables when we generate code, so you can
generate the method like this without reflection.
BTW, why does not the change work with recursive functions
Ye Zheng.
2007/7/2, Xue Yong Zhi <xue.yo...@gmail.com>:
--
Everything is simple!
That is a good suggestion. I will try it when I go back to this issue (may
be next week).
>BTW, why does not the change work with recursive functions
>
If the program is compiled into this:
class FooMethod extends RubyMethod {
public RubyValue a;
RubyValue run (...) {
a = ObjectFactory.fixnum1;
}
}
And we call FooMethod recusivelly, the frames (activation record of a method
call) will share the same set of location variables (all can modify 'a' in
the above example). Each activationrecord should have their own set of local
variables.
_________________________________________________________________
Local listings, incredible imagery, and driving directions - all in one
place! http://maps.live.com/?wip=69&FORM=MGAC01
def test(arg)
p local_variables
eval "#{arg}=2"
p local_variables
end
test("y")
###outputs
["arg"]
["arg", "y"]
as you can see, after eval, it will add a local_variable to the frame,
and the local_variable's name can be dynamic.
the differnent stragety I mentioned above may be compiled with
different optimization levels, like gcc.
what is your guys' opinions?
private RubyArray localVars;
public XXX() {
localVars = new RubyArray();
localVars.add(new RubyString("a"));
...
}
public RubyArray getLocalVars() {
return this.localVars;
}
}
For run method, if we eval something, we can get local vars from it (I
haven't known how to do it), and then add it into our field. Maybe
hash map is a good choice for possible duplication.
2007/7/23, femto gary <femt...@gmail.com>:
>
> do dreamhead's meaning by static or by dynamic?
> if the information is static, then can't handle cases like eval:
>
> def test(arg)
> p local_variables
> eval "#{arg}=2"
> p local_variables
> end
> test("y")
> ###outputs
> ["arg"]
> ["arg", "y"]
> as you can see, after eval, it will add a local_variable to the frame,
> and the local_variable's name can be dynamic.
--
Everything is simple!