[Gambas-user] Custom Control
Doriano Blengino
doriano.blengino at ...1909...
Mon Nov 30 15:27:48 CET 2009
Benoît Minisini ha scritto:
>> Benoît Minisini ha scritto:
>>
>>>> Benoît Minisini wrote:
>>>>
>>>>> In Gambas 3, the /control directory must be put inside the "Project"
>>>>> section.
>>>>>
>>>> Okay, that worked. I was using the control directory automatically
>>>> created when I first created the project. Thanks.
>>>>
>>>>
>>>>> Please provide the details of what you have done, and maybe I will tell
>>>>> you.
>>>>>
>>>> I'm referring to code used when programming the component itself.
>>>>
>>>> For example, in the component code:
>>>>
>>>> Public Sub _new(lVal1 As Long, lVal2 As Long, Optional lVal3 As Long)
>>>>
>>>> If I make the component and try to use it in a project, I have to also
>>>> pass the parent container name. So, if I use:
>>>>
>>>> oVar = New ComponentName(lVal1, lVal2, lVal3, FMain)
>>>>
>>>> It works fine. But if I try to leave out the *optional* argument:
>>>>
>>>> oVar = New ComponentName(lVal1, lVal2, FMain)
>>>>
>>>> I will get "Not enough arguments" from the IDE. If I try:
>>>>
>>>> oVar = New ComponentName(lVal1, lVal2, , FMain)
>>>>
>>>> I will get "Unexpected Comma" from the IDE. And, of course, if I pass
>>>> NUll as the optional argument, it's the incorrect data type for the
>>>> argument. I understand why I'm getting the messages I'm getting. I'm
>>>> just asking is there any way to use an *optional* argument to the _new
>>>> sub of a component.
>>>>
>>>> This isn't something critical. This is just a personal project I chose
>>>> to do as an exercise, to get familiar with Gambas. I always do stuff
>>>> like this whenever I'm learning a new language or (in this case) IDE,
>>>> etc.
>>>>
>>> You get a point there: optional arguments cannot really be used in
>>> constructors, unless you do not use inheritance. Because the rule is that
>>> if an argument is optional, all following arguments are. Which is a
>>> contradiction with the way arguments are used.
>>>
>>> Maybe I should change the way arguments are consumed by inherited
>>> constructors. I mean not inverting them, i.e. inverting them on the
>>> stack, so that you write New MyControl(FMain, lVal1, lVal2...). But this
>>> will uses some CPU.
>>>
>>> I must think about that...
>>>
>> Just my opinion... that may be wrong.
>>
>> An overriding method (and constructors too) should take the full control
>> on what happens. So, the overriding method receives the arguments it
>> needs (probably a parent window too, but who knows?), does with them
>> whatever it likes, and in this process calls the inherited method when
>> it likes. In this point of view, it would be not correct to have some
>> automatic argument consuming. It is true that the programmer will have
>> to explicitly call the inherited constructor, which in turn will call
>> its inherited constructor and so on, but this is the whole philosophy.
>> Suppose that you write a component which can be child only of certain
>> parents (don't know... vboxes)? If you pass the wrong parent when
>> instantiating it, the constructor can check for this and raise an
>> exception. If the argument (parent in this case, but the same applies to
>> any other argument) is consumed by something else, this check is not
>> possible. I think this thought is more general than this stupid example
>> I can produce just now. This would solve the optional parameters too.
>>
>> Regards,
>> Doriano
>>
>>
>
> The reason I did such a thing (each inherited constructor consume arguments)
> is encapsulation.
>
> Inheritance is fully dynamical: it is resolved at class loading, and you may
> have no idea of what you are really inherit - you see the interface only,
> think inheriting a native class.
>
Uhm... don't know if it is a good idea to "have no idea of what you
really inherit"...
The encapsulation, in this case, would be extreme! The reason to inherit
would cease.
> So, if the constructor of the new class had full control, it would break the
> encapsulation: the constructor of the inherited class may not be executed, or
> other strange things may happen.
>
This is exactly the point. I wrote "the programmer will have to
explicitly call the inherited constructor", and this is annoying, but
this is the only way to let the programmer do things before and/or after
the inherited method is called (I can think of other ways, but more
complicated).
There are no compromises - either you (Benoit) do the right thing for
the programmer, keeping it from errors *and* versatility, or you give it
full control, letting it make mistakes. Or is there a compromise?
> So I decided that if a class B inherits a class A, then instanciating B will
> execute at least the same code than instanciating the class A. And so come the
> idea of consuming constructor arguments when calling all inherited
> constructors one by one.
>
> By passing constructor arguments is order since the last revision, and not in
> reverse order as before, the last constructor can have optional arguments. The
> inherited constructors optional arguments must be pass anyway, they are not
> optional anymore.
>
Things are valid sometimes yes and sometimes no?
If I write a component having optional arguments in its constructor, and
then inherit from it, those optional arguments are no more optional?
Well, one could live with it... but this very case is the one which
breaks encapsulation: optional (or default) values are the ones that let
a software grow and get better without breaking dependent things. On the
other hand, I think nobody wants that gambas grow up to be another java,
so some simplicity is welcome. It seems that there is not many people
that actually uses inheritance - the more complicated inheritance is,
the less people will use it.
Regards,
Doriano
More information about the User
mailing list