[Kde-bindings] QtRuby virtual method callbacks

Richard Dale Richard_Dale at tipitina.demon.co.uk
Mon Jul 21 19:30:58 UTC 2003


On Saturday 19 July 2003 04:27, Ashley Winters wrote:
> --- Richard Dale <Richard_Dale at tipitina.demon.co.uk> wrote:
> > > mmh, but why?
> > > "$" is for scalars, and I think that's what all languages will use
> >
> > for
> >
> > > marshalling "int&".
> > > char** ought to be fed by the target language's equivalent of an
> >
> > array of
> >
> > > strings, so "?" looks right aswell...
> >
> > This is the code in qtruby.rb for references:
> >
> > 			for arg in args
> > 				if arg == nil or isObject(arg)
> > 					method << "#"
> > 				elsif isRef(arg)
> > 					method << "?"
> > 				else
> > 					method << "$"
> > 				end
> > 			end
> >
> > I 'made up' isRef() - there is no 'ref' in ruby as far as I know.
>
> The case of nil/undef is handled specially by PerlQt's interface to
> smoke. In that case, it could be a null string (undef $), null object
> pointer (undef #) or a null array/other pointer (undef ?). In order to
> fairly pick a matching prototype, all of these candidates are returned
> from the matching function. Psuedo-code time:
>
> If you will allow me to digress into psuedo-Perl for a moment:
>
> @candidates = qw(functionName);
>
> for my $arg (@args) {
>     if($arg is undef) {   # psuedo, remember?
>         @candidates = map { $_ . '$', $_ . '#', $_ . '?' } @candidates;
>     } elsif($arg is scalar) {
>         @candidates = map { $_ . '$' } @candidates;
>     } elsif($arg is object) {
>         @candidates = map { $_ . '#' } @candidates;
>     } else {    # !nil and !scalar and !object
>         @candidates = map { $_ . '?' } @candidates;
>     }
> }
>
> # @candidates is now a list of prototypes which match the arguments
> # passed by the program. sort them how you see fit...
>
> And, for the specific case of the QApplication constructor, PerlQt
> hijacks it and automatically passes the argc argument. It does this so
> that PerlQt can read back in the argv after Qt muchs with it and
> replace the perl @ARGV array with the proper values.
>
> In the general case though, picture this:
>
> void QFoo::foo(int&);
>
> x = new QFoo
> y = 1
> x.foo(y)
>
> Your smoke detector will generate a foo$ prototype since it's being
> passed a scalar variable (y == 1), which is what smoke provides in the
> case of int&. If you pass a nil variable to it, your smoke filter
> (hehehe) will try to match the names foo$, foo#, and foo? as per my
> above psuedo-code. Since my QFoo class does indeed have a foo$ and none
> of the eithers, it matches and gets called.
Ah I see! The trouble is the pseudo-code looks a lot like the actual perl, and 
I'm not much of a perl expert at all, and didn't understand what it means. 
But it shouldn't be too difficult to sort out - one of my ruby books  'The 
Ruby Way' has a really good section called 'From Perl to Ruby' - I think it's 
just a matter of going through all the perl type mappings and seeing how they 
compare with ruby types.
>
> Enough from me. Excellent work, Richard!
Thanks - it's great how well your 'Smoke Marshalling Framework' could be 
adapted to ruby, when you probably didn't have ruby in mind when you were 
designing it. I don't think it would be too difficult to have the ruby 
runtime load a perl KPart, and the ruby plugin would be informed of which 
virtual methods had been overriden in perl. When the KPart was running and 
there was a virtual method callback the ruby plugin would first check that 
the method hadn't been overriden in ruby, and if not then it would call the 
perl version.

-- Richard


More information about the Kde-bindings mailing list