[Gambas-user] a few suggestions for improvement
Benoit Minisini
gambas at ...1...
Wed Jan 5 16:46:00 CET 2005
On Wednesday 05 January 2005 15:24, Toni Schornboeck wrote:
> Hello Folks.
Hello,
>
> First I want to say that I like the Gambas Environment very much.
> But there are a few things that I don't like.
> I want to explain what I don't like, why and how it could be improved.
> I would be glad if you could answer me and discuss my proposals.
>
>
> After a Form is closed, the object still lives, but at the same time is
> dead.
> I'd like to write code like:
> dim f as Form
> f=new Form(foo)
> f.ShowModal()
> return f.Result
>
> or something like that. But it is not possible, because f dies after
> "ShowModal()"
> I think that is unecessary. f should stay alive until it gets out of scope.
> It would be OK, if a closed form can never be opened again, therefore a
> f.ShowModal()
> f.ShowModal()
> could raise an error.
>
> Take for example a InputBox. AFAIK the currently best solution is:
> static public function Run() as String
> dim f as InputBox
> f=new InputBox
> f.ShowModal()
> return value
> end
>
> private static value as String
>
> public sub Form_Close()
> value=Text1.Text
> end
>
> This Solution is just Plain ugly and can lead to Bugs, when 2 InputBoxes
> are open at the same time.
Well, I dont find that ugly, and if you have several instances of your form,
just don't declare the variable static.
>
>
>
> A constructor has always to be public. Why?
It is by design.
> I'd like to declare a constructor private to force the user of my code to
> use a static
> construct (that means: a static function that returns the object).
> This can sometimes be useful, for example when using a factory to prohibit
> the user from directly instanciating
> objects.
>
At the moment, I don't see any mean to do that cleanly.
>
> This leads to another point: friends could be useful or something like Java
> Packages where one can declare a method
> as package private.
>
In Gambas, public means exported. If something is private in a class, then the
interpreter can't access it from outside the class. So, constructors,
destructors, event handlers... need to be public, or the interpreter won't be
able to call them.
>
> optional parameters are very useful, but why can I only assign a default
> value to primitive types?
> private sub foo(optional i as integer = -1)
> is perfectly legal, but
> private sub foo(optional o as Bar=new Bar(baz))
> is rejected :(
> It would be nice to define default values also for objects.
I think it is just something to change in the compiler. So it may be
possible :-)
>
> The workaround using
> if isnull(o) then o=new Bar(baz)
> doesn't always work.
> Because NULL may be a perfectly legal value in some cases.
>
>
Well, in your example, NEW will never return NULL.
>
> for each on collections acts weird.
> for each v in col
> print col.Key & "=" & v
> next
> This looks ugly. col is changed even though I don't write to it, but just
> read values from it.
> And it isn't really intuitive to look for key in col...
I don't unserstand what you say. Collection.Key is just a read-only property
that returns the key of the last entry accessed in the collection. I don't
see where the collection is modified during the iteration...
>
> It would be nice if we could introduce an iterator concept.
> But this is quite controversal, so I would like to get your opinion first,
> before thinking
> too far.
>
A class can have a '_next' method to implement iteration. But only a native
class (written in C/C++) can use that.
>
>
> I really miss a 'super' or 'base' keyword to access the Baseclass from
> within the derived class.
> In my current work I have this Code:
> PUBLIC FUNCTION doGetQuery() AS SelectQuery
> DIM query AS SelectQuery
> DIM super AS DependentDataSource
>
> IF IsNull($con.Value()) THEN RETURN NULL
>
> super=ME
> query=super.doGetQuery()
> query.AddWhere($field & "='" & CStr($con.Value()) & "'")
>
> RETURN query
> END
>
> DependentDataSource is the Baseclass.
> I have to do an upcast (without casting operators, I'll talk about them a
> bit later) to access
> doGetQuery() of the base class.
> It would be much nicer if I could simply write
> SUPER.doGetQuery()
>
You are right, SUPER is missing. It's in my TODO list.
>
>
> This leads to another point:
> Why can't I define which parameter are passed to my base class?
> Take for example a XML Parser. There are a few Node classes, all derived
> from BaseNode.
> Every Node contains an array of allowed child nodes.
> One could write:
> SomeNode.class:
> public sub _new()
> 'call base constructor
> super(allowedChildren)
> end
>
> but currently this isn't possible because the user has to specify the
> params.
> but in this code only the class itself knows which child nodes are allowed
> and the user
> shouldn't care.
>
> The workaround using set-Methods to set the allowed children afterwards is
> not perfect, because
> the child nodes should be set exactly once when the object is instaciated
> and shouldn't change
> later.
>
Try that:
BaseNode.class:
PUBLIC SUB _new()
...
END
SomeNode.class:
PUBLIC SUB _new(allowedChildren)
...
END
Each class in the inheritance hierarchy consumes the parameters passed to the
constructor.
>
>
> I already mentioned the lack of casting Operators.
> Take for example another code from my current work (stripped down):
> DIM control AS Control
>
> SELECT CASE type
> CASE "select"
> control=NEW ComboBox(detailFrame) AS "EditControls"
> Object.SetProperty(control, "ReadOnly", TRUE)
> END SELECT
>
> this factory creates a control depending upon a parameter.
> It has to set a few parameters, like ReadOnly=TRUE
> It would be nice if I could write:
> ((ComboBox)control).ReadOnly=TRUE
> or
> Cast(ComboBox, control).ReadOnly = TRUE
> or something like that.
If I remember, you can do ComboBox(...) to cast to ComboBox. Test it to see if
it really works.
>
> If I could declare variables everywhere I like would also help.
>
>
> This leads to: variables must be declared at begin of function
> why is that?
>
> In C it was a pain in the ass, so they removed this restriction with C99
> and no other major language hast
> that restriction. Even VB doesn't ;)
I find declaring variable everywhere a source of confusion and unreadable
code. So I force them to be declared at the beginning of the function. And
one by line at the moment ?
>
> It would be really important to allow the user to declare variables as
> local as possible.
> it is even more important because gambas functions tend to be bigger than
> for example Java or C++ functions
> (my own personal expierence)
>
You are not compelled to write large functions...
>
>
> A very controversal point is:
> no RETURN will return NULL
> I'd prefer a warning when I forgot to write a return statement within a
> function.
It is by design.
>
>
>
> One thing that really annoys me is:
> arr.Add(new Foo(bar))
> doesn't work.
>
> I have to write
> dim t as Foo
>
> t=new Foo(bar)
> arr.Add(t)
>
> I worked around it by providing a static public make function:
> static public make(p as Bar)
> dim obj as Foo
> obj = new Foo(p)
> return obj
> end
> so I can write
> arr.Add(Foo.make(bar))
>
> but it would be nice if I could simply write new Foo everywhere where I can
> put a Foo object.
>
It is by design too. I didn't want to make NEW a true operator. But it is just
a compiler restriction. The interpreter don't care.
For example, you can do
arr.Add(New("Foo", bar))
>
>
> another nice feature would be, if one could declare a variable inside a for
> statement:
>
> for i as integer = 0 to 10
>
> i would be accessably only within the for loop
> this would be very convenient. it would also help to hold variables as
> local as possible.
> one normally uses a loop variable i just for looping and nothing more so it
> would be really nice if one
> could express the use of i this strong and obvious.
>
Same remark than before. And I don't see the benefit of having variables "as
local as possible". It will change nothing in interpreted code.
>
>
> Why doesn't gambas do virtual dispatching?
> I have a base class called Base and a derived class called Derived.
> bot implement the method GetQuery()
>
> When I have a reference to Base (which really is a reference to Derived,
> but was upcast)
> and call GetQuery() it will call Base's GetQuery instead of Derived's one.
>
> I have to use
> Object.Call(obj, "GetQuery")
> but this isn't so nice.
>
> So I worked around it by implementing GetQuery only in Base which looks
> like:
> public function GetQuery() as Foo
> return Object.Call(ME, "doGetQuery")
> end
>
> Derived and Base implement also doGetQuery which does the actual work.
> But the drawback is: doGetQuery can't be private, because Object.Call
> wouldn't have access to it...
>
> I would like to see virtual dispatching in gambas improved, because
> currently it is (IMHO) a mess.
>
You are absolutely right. I just change the interpreter in the 2.0 so that
virtual dispatching work. As soon as I release the first developmement
version (1.9.1), you will be able to test it and tell me if things are right.
>
>
> The next issues are about the IDE gambas:
> I'd love to see the possibility to set the Tabstop ordering.
> currently I have to edit the *.form files and reorder the components. that
> could be improved!
TabOrder = ZOrder, so you just have to modify the second to change the first.
>
>
>
> It would improve the usability of the IDE if I could create directories to
> store my class and form files
> currently I have about 30 *.call files. conceptional there are 3 modules.
> if i could store them in 3 directories
> it would improve the management of them a lot.
>
I was thinking of letting the IDE show an ordered and hierarchical view of
forms, classes and modules, even if they are stored flat in the project
directory.
>
> a minor issue: the executale file of my project contains a lot of
> information that shouldn't be there
> for example:
>
> Project=ReportGenerator
> Title=ReportGenerator
> Startup=Report
> TabSize=2
> Argument=-h localhost -l schorny -p <snip> -n akademie
> Version=0.0.16
> Library=gb.db
> Library=gb.xml.libxml
> SnapToGrid=1
> ShowGrid=1
> Snap=8
> Localize=0
> KeepDebugInfo=0
> ControlPublic=0
> ExecPath=/home/schorny/code/ReportGenerator/report
> Prefix=0
>
> I think most of them are unecessary. And "Argument" is a bit dangerous - it
> contains the params that the IDE should use when
> calling the program. as you can see: it contains the login information for
> my test db. I don't want to give them to every user ;)
>
Well. It is a point I didn't think about :-) I note it in the TODO list.
>
>
> even though if have postet a lot of critic: I like gambas.
> Otherwise I wouldn't have convinced my boss to use Gambas for our Linux
> Clients ;)
>
> currently the best RAD environment for Linux/KDE -> congratulations!
Thank you!
Regards,
--
Benoit Minisini
mailto:gambas at ...1...
More information about the User
mailing list