Kenichi Komiya <kom / mail1.accsnet.ne.jp> wrote in message news:<gGB97.12858$WD1.528847 / e420r-atl2.usenetserver.com>...

>I read the README of Dynamic-ORBit with great interest.  I am
>interested in partially because I want to use CORBA with Ruby,
>someday.  But mostly, my motivation is to pick up some idea to
>improve my Ruby IDL mapping.  But I am not working on CORBA.
>
>I am developing the rbXPCOM --- XPCOM Ruby language binding.
>
>    <prug>http://rbxpcom.mozdev.org</prug>
>
>XPCOM is an acronym of Cross Platform COM (Component Object
>Model) developed and used by the Mozilla project.  It uses a
>modified version of OMG IDL to define interface of components
>(They call it xpidl).  I see there are some design issues shared
>between Ruby CORBA effort and my project.
>
>I would like to cooperate to create better language mapping for
>Ruby and idl like interface.  Just reading your README already
>made me rethink the way I map idl interface to Ruby module.
>Maybe I will talk about this later.
>

It would be *very* helpful to me if someone could provide an English
translation of Dai's documentation of his IDL-Ruby mapping.  I don't
want needless duplication of effort, and I certainly don't want to
make design mistakes that could be avoided with enough knowledge of
other people's approaches.

>For now, I would like to share my experience to "constant" and
>"out parameter".
>
>  CONSTANT
>----------
>
>from your README
> > For at least two reasons, IDL constants are *not* mapped to Ruby
> > constants.  In the first place, as we all know, Ruby "constants" are not
> > really constant.  This is at variance with the "immutable" semantics
> > implicit in IDL.  In the second place, Ruby constants must begin with
> > a capital letter.  This is clearly an unreasonable requirement to place
> > on CORBA implementors who write their IDL with other languages in mind.
>
>The first argument is also applied to all Ruby programs.  I
>guess many Ruby programmers can live it.  For the second
>problem, my solution is simply upcase the first letter if it is
>lower case.

I thought of using this simple name-mangling but wanted to avoid it
because I like the idea of being able to write code with exactly the
same identifiers that appear in the IDL.  Now that I think about it, I
guess this wouldn't create name collisions in the IDL, since IDL
identifiers are treated as case-insensitive, so you couldn't legally
have, say, two constants named pi and PI in the same scope.  I should
have thought this through a bit more carefully.  Name mangling might
not be as bad as I had thought.

> > Therefore I implement constants as methods returning the value of the
> > constant.  E.g.,
> > //IDL
> > module Foo {
> > 	const float pi	= 3.14159265;
> > };
> >
> > #Ruby
> > module Foo
> >  def pi
> >    3.14159265
> >  end
> > end
>
>I actually tried this idea in version 0.0.1 of rbXPCOM.  I
>discarded, though.  Due to different scoping rules, it is more
>confusing than helpful, IMHO.
>
>module Foo
>   Pi = 3.14159265
>   def pi
>     3.14159265
>   end
>end
>
>class Bar
>   include Foo
>   p Pi
>   p pi    # error
>   def Bar.bar
>     p Pi
>     p pi  # error
>   end
>end

I thought I solved this by eval'ing "module_function :constant" right
after eval'ing the method def for the constant, but I was wrong.  I
guess I was thinking that all module functions of a module become
class methods of any class that includes the module, so that

class Bar
   include Foo
   p pi    # error
end

was equivalent to

class Bar
  def Bar.pi
    Foo.pi
  end
  p pi
end

but I see from running the code that I was wrong.
Maybe this is why there are two separate C functions,
define_module_function and define_singleton_method?  Thanks for
bringing this to my attention.

>And, if the initial letter of a idl constant is just happen to be
>upper case, you have another problem.
>
>module Foo
>   def Consant; 2 ; end
>end
>
>Foo::Constant     #=> NameError: uninitialized constant Constant at
Foo
>
>Above all, Ruby programmer will upset if Foo.constants returns [].

Yeah, I guess I just expected the client programmer to use "." to
qualify IDL constants rather than "::" (as in the example code), but
this is certainly not in accord with the POLS.

>
>  OUT PARAMETER
>---------------
>
>from README
> > //IDL
> > interface Foo {
> > 	long do_it(in long in_arg, out long out_arg, inout long
> >		inout_arg);
> > };
> >
> > #Ruby
> > #somehow get reference myFoo to Foo object
> > ret_val, out_arg, inout_arg_ret = myFoo.do_it(in_arg, inout_arg_par)
>
>I just looked the testcase code and gathered that you do not
>pack the returned value to an array if there is only one value
>to return.  Is it correct?  If so, rbXPCOM uses exactly same
>mapping.

Yes, this is correct.

>You have two experimental mappings to simulate call-by-reference
>semantics.  I am interested in how well they will turn out.  It
>seems they both suffer the disadvantage of requiring 'variables
>declaration', though.

This is only awkward for out parameters, since inout params must have
some initial value anyway.

>From some coding experience with Mozilla's components, I learned
>following things (at least for Mozilla's codebase).
>
>   * There are few method that actually return useful multiple values.
>     (Many methods return array or string and its size.  But the
>     size is redundant as Ruby object already know its size.)
>
>   * Use of inout is rather rare.
>
>So, I decided I do not need elaborate mapping to deal with the
>call-by-reference thing, at least for now.  I just sticked to
>what Python CORBA mapping is using for years.

I agree that inout is fairly rare, and that use of it in IDL usually
indicates poor design.  (I don't think I would ever use it myself.)  I
think it's mainly in the IDL spec because C and C++ were the original
target languages, and call-by-reference is the normal way to simulate
multiple return values in those languages.  But I put this stuff in
largely for the "coolness factor", and I don't see any reason to
remove them, since they shouldn't be a problem to anyone who doesn't
explicitly use them (i.e. either include "inout" as the last parameter
or supply a block with the method call).
 
>Best Regards,
>Kenichi Komiya.

Thanks for the feedback.  It's given me a lot to think about :-)