Mario S. wrote:
Hello Ridge,
Hi Mario,
Thanks for joining the discussion. Hopefully, we can have some
significant mindshare.
Let me explain this a bit further in detail as to the process the
Garbage
Collector, and wxRuby’s own classes work about things.
On Sun, Jan 4, 2009 at 5:22 PM, Ridge M. [email protected]
wrote:
to make it a fully-qualified class, huh?) If I understood your
message, the GC is making decisions based on the type (MenuItem).
Isn’t this just what an object-oriented system should not do?
What Alex was trying to explain here, is that some classes, such as
Menu,
MenuItem, Rect, Point, and various other ones, are considered
Information
Classes. Information classes only hold the information of what is
relevent
at the point and time of the execution of the code. To make it a bit
more
clearer to understand, let’s take the problem of MenuItem. Imagine that
MenuItem is a Ruby Struct class.
Defining it as such:
MenuItem = Struct.new(:title,:id,:parent,:bitmap)
my_new_menu_item =
MenuItem.new(“&Open”,Wx::ID_OPEN,my_file_menu,Wx::ICON_FOLDER)
This is a silly mockup of what I’m trying to explain, but this is what
it
boils down to. Once you actually create the control, there’s no further
need to reference this control, till something happens with it, such as
evt_menu(Wx::ID_OPEN), this is where we re-retrive the actual wxRuby
control, for any association needed to do special things, such as
changing
the title of the Menu item. There is no other things you can really do
with
a MenuItem, aside from either updating it, or deleting it. Atleast, as
far
as wxWidgets is concerned. Therefore, if you don’t store the instance
of
the MenuItem in a variable, where the Garbage Collector can see that it
is
still being referenced within your code, Ruby thinks that it is no
longer
needed, and therefore frees it up for others to use.
Your explanation is clear and I appreciate your effort to make it so.
I’m hoping I can be as clear.
I understand your perspective but respectfully disagree with your
assertion:
“There is no other things you can really do with a MenuItem, aside
from either updating it, or deleting it.”
One of the hallmarks and most powerful aspects of an object-oriented
language is that new developers are able to extend the capabilities of
existing classes via subclassing (in ways that the class originators
didn’t necessarily anticipate). By constraining classes in arbitrary
ways (IMHO), that power is severely limited.
I do understand (I think) your desire to free up memory that is not
being used. However, there are already mechanisms in place: scoping
rules and delete. Please help me understand why these mechanisms
are not sufficient in this case.
If you are providing extra GC as a convenience, then I respectfully
submit that the developer should be permitted to accept or reject
that convenience so that his/her code will behave as expected. By
forcing extra GC upon the developer for certain classes that are
considered “information classes” by the originators, the code
(originally attached) behaves in a most unexpected way:
On (approximately) the 25th time a class instance is used (in this
case a menu appears), the (subclassed) menu items suddenly lose
their identity and instead assume the identity of their superclass.
Until I have the opportunity to understand your perspective more
fully, I respectfully assert:
Class instantiations should maintain their existence and identity
until they move out of scope or until they are expressly deleted.
Some questions:
Is this a generic ruby issue (or is it unique to wxruby)?
This is a unique problem with wxRuby. It’s mainly a decision of what we
need to continue to keep tracking, without tracking every single object
created.
I appreciate your candidness. I’m hoping we can find a way for
wxruby to be more ruby-ish.
What triggers the GC ? (While testing, I found that the “rewrapping”
occurred whether or not I called find_item. Just repeatedly
selecting
the MyMenuItem, which triggered a menu_event and caused on_menu_event
to be called, would result in the MyMenuItem being “rewrapped” as a
MenuItem. As such, over-riding MyMenu#find_item would not be
expected
to solve the problem.)
Garbage Collection, especially in a wxRuby app, happens quite often, as
there are many times that a Ruby object is temporarly created, to
associate
it with a wxWidget’s object. And 9 times out of 10, it’s a temporary
reference, which is immediately de-referenced within the code, and when
Garbage Collection runs again, it’ll delete this instance. However, in
the
particular instance of Menu Event (evt_menu), there is no particular
reference to review to say, Oh, this needs to be referenced by previous
instance creation.
I understand your point that object creation is often
temporary and that, with regard to Menu events, there
is some difficulty in knowing what is a temporary
instantiation and what is not.
However, again I respectfully submit that it seems
ill-advised to use probability as a solution without
offering an alternative.
Unfortunately, in this case, the procedure that Alex has referenced,
would
be the best way, as it would be nearly neigh improbable to track every
single custom class creation, between wxWidgets and wxRuby. As with
wxWidgets, there’s nothing to allow us to track custom classes created
in
Ruby of wxWidgets classes, least we create a new memory structure, that
would inherit from one of our classes. It may be doable, in the Ruby
level,
at the actual Ruby level itself, but not on the C++ Side.
Thank you for your trying to educate me about wxruby and
for offering work-arounds that I can put in my code.
I am not sure at this point why you seem so concerned about
“tracking every custom class creation” when, in both C++ and
ruby, subclassing is such a fundamental part of the language.
There are already mechanisms available to the developer to
handle memory bloat (scoping rules and express deletion of
unneeded instantiations).
I am very happy that you folks are working hard to support
wxruby. wxruby seems to be a comprehensive, cross-platform
GUI toolkit that could meet my needs. I respect your
willingness to discuss issues such as the present one.
I also respect your willingness to explain why you have
made the decisions you have made.
I hope you can also understand my surprise to be faced
with such an unexpected problem on the first day of wxruby
development. I want to believe that there is a solution
that will meet the needs of all developers.
At the risk of sounding bold, would you consider supporting
the following:
"wxruby fully supports subclassing, respecting scoping rules
to handle object persistence. However, developers should be
advised that they can unwittingly consume memory resources
if they do not properly manage their objects, specifically
if they do not delete objects when they are no longer needed.
We have learned this through bitter experience.
"Since object management can be a daunting and tedious task
for the developer, wxruby provides a super-cool garbage
collection facility that can automatically delete objects
that are no longer referenced, significantly reducing runtime
memory usage. When creating your application, simply set
supercool_gc to true, as in the following example:
class MyApp < App
def on_init
@supercool_gc = true
end
end
"The following classes are considered ‘information classes’
and will be specifically targeted by the GC:
Menu
MenuItem
(any others)
“If you subclass any of the information classes, please
note that you may need to disable supercool_gc for
those classes.”
At this point, I’m concerned that I will find other
instances in which the GC will impede my development
progress. But I hoping this will not be the case. It
may be that the problem is limited to menu items and
that the GC works beautifully in all other cases. In
that case, developers would want to take advantage of
the GC and would alternatively perfer to have a specific
@supercool_menuitem_gc flag so that they could manage
their menuitems independently but have the GC manage
the rest of the objects. Or, perhaps there should be a
flag for each “information class”. I’m hoping we can
sort this out.
As noted, since I’m a wxruby newbie, I welcome further
explanations to help me understand why the GC must behave
as it does. I would very much like wxruby to succeed.
Cheers,
Ridge