ES schrieb:
Wouldn't it be possible to override the TrueClass, NilClass
and FalseClass methods to yield the correct behaviour for
this object? I'm assuming 'if something' expands to
'if something == true' or something like that?
If you look at the Ruby source code (this is 1.8.2), in eval.c:
case NODE_IF:
if (trace_func) {
call_trace_func("line", node, self,
ruby_frame->last_func,
ruby_frame->last_class);
}
>>> if (RTEST(rb_eval(self, node->nd_cond))) {
node = node->nd_body;
}
else {
node = node->nd_else;
}
goto again;
This is the code to handle an if statement. The marked line is the code that
evaluates the condition. The "then"-part of the if statement is executed iff
the
RTEST macro returns true (in C). RTEST is defined in ruby.h as:
/* special contants - i.e. non-zero and non-fixnum constants */
#define Qfalse 0
#define Qtrue 2
#define Qnil 4
#define RTEST(v) (((VALUE)(v) & ~Qnil) != 0)
The objects false, true, and nil are encoded internally as 0, 2, and 4
respectively. (You can get those values in Ruby with "p false.id".) The only
values for which RTEST returns false (in C) are the values 0 and 4, in other
words the objects false and nil. So more or less
if something
expands to
if something != nil && something != false
Well, this *would* be overridable. If, however, the test is done at the C
level through direct object ID comparison, things are a bit more complicated.
The only option, then, would be to masquerade as Qnil while adding the
necessary behaviour.
I suppose the question is, then, is it necessary to have the above behaviour?
As I understood it, the desired functionality was something like (my syntax):
ob.not_nil?.do_something
Conceptually expands to:
ob.do_something unless ob.nil?
For this purpose, it should be sufficient to add a method to both Object
and NilClass. NilClass could then return an object that simply consumes
all methods fed to it and propagates itself after each call, like was
described in the original post as far as I can recall its contents. This
behaviour would then not be accessible except when using NilClass#not_nil?
so it wouldn't cause problems in other conditionals. Is there a use case
where this would cause a problem, or why is it desirable that the explicit
comparison be allowed for the special NIL and not just the chaining?
Again, sorry if this has already been covered; feel free not to reply,
I'll read the NG in the evening. I'm just bored at work 
I think Christian is right that you cannot work around this in Ruby. (Maybe
Florian Groß can do it...)
Regards,
Pit
E
···
On Mon, February 21, 2005 8:04 pm, Pit Capitain said: