Changing class of object foobar

M

Marc Heiler

Hi

Please no "redesign" proposal as in "do not try to do this
at all" - I really want to know if the following is possible,
and if it is, how. And if it is not, I can't try anyway
and have to rethink/redesign the approach to it _anyway_ :)
Thanks.

I spent a little time digging through ruby-prototype, dl/struct,
evil.rb but given my lack of knowledge, ended up more
confused than enlightened.

A somewhat lengthy explanation follows, but please don't tie
this too much to my specific problem at hand, in actual
practice I am more interested in how to have an object
of class X become an object of Class Y instead

__________________________________________________________________

I have a general class, a button. This class will be responsible for
providing all required datasets to "become" a "specialized" button.

With "specialized", I really mean a Button for i.e. a specific widget
set, like Qt. So that the user can work with a Qt button, or a
gtk button, or a FXRuby button and so on, but without the need to
care about the internals and widget-specific problems.
This is just to help the user focus on one language aspect (describing
his widget once, and only once) and then have code help him to
realize the rest. (In reality i'd later plan to separate the
layout even more to use "classes" similar to Cascading Style Sheets
for "grouped" styling, but ignore this for now please)

The moment the user needs this "prototype widget" to be specific (our
button in this case, but there will be more abstract widget sets in the
future, if this works) he "converts" it to a certain toolset.
For example, this button becomes FXButton.new now.

The reason for the abstraction is because it makes no sense
to restrict yourself to one specific widget set, if the logic itself
is pretty much the same in all toolsets (Clicking, mouse moving,
actions,
especially colours and padding etc..) and should be easily
accessible to a human reader too without the need to pick a
widget-specific solution, like gtk rc_files.

Enough pretext, now the question! :)

How can I convert my object "foobar" of "class Button"

foobar = Button.new

to become a "real" Gtk::Button for instance?

Inside class Button I can not modify self, so I wonder if
there is any option at all to convert to the Gtk::Button.
I can create a new Gtk::Button inside class Button easily,
with all the required data, but it seems my created object
is never able to leave its class Button state. At best
it can only do a "return Gtk::Button" in the end.

I am glad for any ideas and help.
 
C

Chris Carter

Hi

Please no "redesign" proposal as in "do not try to do this
at all" - I really want to know if the following is possible,
and if it is, how. And if it is not, I can't try anyway
and have to rethink/redesign the approach to it _anyway_ :)
Thanks.

I spent a little time digging through ruby-prototype, dl/struct,
evil.rb but given my lack of knowledge, ended up more
confused than enlightened.

A somewhat lengthy explanation follows, but please don't tie
this too much to my specific problem at hand, in actual
practice I am more interested in how to have an object
of class X become an object of Class Y instead

__________________________________________________________________

I have a general class, a button. This class will be responsible for
providing all required datasets to "become" a "specialized" button.

With "specialized", I really mean a Button for i.e. a specific widget
set, like Qt. So that the user can work with a Qt button, or a
gtk button, or a FXRuby button and so on, but without the need to
care about the internals and widget-specific problems.
This is just to help the user focus on one language aspect (describing
his widget once, and only once) and then have code help him to
realize the rest. (In reality i'd later plan to separate the
layout even more to use "classes" similar to Cascading Style Sheets
for "grouped" styling, but ignore this for now please)

The moment the user needs this "prototype widget" to be specific (our
button in this case, but there will be more abstract widget sets in the
future, if this works) he "converts" it to a certain toolset.
For example, this button becomes FXButton.new now.

The reason for the abstraction is because it makes no sense
to restrict yourself to one specific widget set, if the logic itself
is pretty much the same in all toolsets (Clicking, mouse moving,
actions,
especially colours and padding etc..) and should be easily
accessible to a human reader too without the need to pick a
widget-specific solution, like gtk rc_files.

Enough pretext, now the question! :)

How can I convert my object "foobar" of "class Button"

foobar = Button.new

to become a "real" Gtk::Button for instance?

Inside class Button I can not modify self, so I wonder if
there is any option at all to convert to the Gtk::Button.
I can create a new Gtk::Button inside class Button easily,
with all the required data, but it seems my created object
is never able to leave its class Button state. At best
it can only do a "return Gtk::Button" in the end.

I am glad for any ideas and help.

Changing the class of the Button object won't work. I would suggest
just storing the new object in an instance variable in the Button
object.
 
N

Noah Easterly

Hi

Please no "redesign" proposal as in "do not try to do this
at all" - I really want to know if the following is possible,
and if it is, how. And if it is not, I can't try anyway
and have to rethink/redesign the approach to it _anyway_ :)
Thanks.

I spent a little time digging through ruby-prototype, dl/struct,
evil.rb but given my lack of knowledge, ended up more
confused than enlightened.

A somewhat lengthy explanation follows, but please don't tie
this too much to my specific problem at hand, in actual
practice I am more interested in how to have an object
of class X become an object of Class Y instead

__________________________________________________________________

I have a general class, a button. This class will be responsible for
providing all required datasets to "become" a "specialized" button.

With "specialized", I really mean a Button for i.e. a specific widget
set, like Qt. So that the user can work with a Qt button, or a
gtk button, or a FXRuby button and so on, but without the need to
care about the internals and widget-specific problems.
This is just to help the user focus on one language aspect (describing
his widget once, and only once) and then have code help him to
realize the rest. (In reality i'd later plan to separate the
layout even more to use "classes" similar to Cascading Style Sheets
for "grouped" styling, but ignore this for now please)

The moment the user needs this "prototype widget" to be specific (our
button in this case, but there will be more abstract widget sets in the
future, if this works) he "converts" it to a certain toolset.
For example, this button becomes FXButton.new now.

The reason for the abstraction is because it makes no sense
to restrict yourself to one specific widget set, if the logic itself
is pretty much the same in all toolsets (Clicking, mouse moving,
actions,
especially colours and padding etc..) and should be easily
accessible to a human reader too without the need to pick a
widget-specific solution, like gtk rc_files.

Enough pretext, now the question! :)

How can I convert my object "foobar" of "class Button"

foobar = Button.new

to become a "real" Gtk::Button for instance?

Inside class Button I can not modify self, so I wonder if
there is any option at all to convert to the Gtk::Button.
I can create a new Gtk::Button inside class Button easily,
with all the required data, but it seems my created object
is never able to leave its class Button state. At best
it can only do a "return Gtk::Button" in the end.

I am glad for any ideas and help.

Why convert when you can just lie? Does the user ever have to know
what toolset they're using?

One way of lying would be to have your 'abstract' Button just be a
delegator that delegates to what ever
Toolset's button is actually being used. See 'ri SimpleDelegator' and
other such documentation.

Or, if you don't think you're going to dynamically change Toolsets
that often, you could have your Button::new method 'lie' by
overwriting it to return an instance of whatever's Toolkit's button
you actually want to use. Or heck, you wouldn't need to go that far
even. You could just have the user use a Toolset that you declare,
something like:

require 'toolset'
include Toolset
button = Button.new
# ....

And then, have toolset be something like:

#Toolset = Gtk
Toolset = Qt

For more dynamic scenarios (you want to make sure their code runs
against a set of toolsets), you could pass them the toolset in another
manner.

I'm honestly not saying "Please don't do this at all"; I'm actually
shooting for something more like "Does this make it so you don't need
to?"
 
W

Wilson Bilkovich

How can I convert my object "foobar" of "class Button"

foobar = Button.new

to become a "real" Gtk::Button for instance?

foobar = Gtk::Button.new
 
R

Rick DeNatale

foobar = Gtk::Button.new


This only binds the VARIABLE foobar in the current scope to a
different object, it DOESN'T change the OBJECT which foobar pointed to
originally. So for example

def dub_gtk_button(button)
button = Gtk::Button.new
puts "in dub_gtk #{button.class}"
end

button = Button.new
puts "before #{button.class}"
dub_gtk(button)
puts "before #{button.class}"

will print:

before Button
in dub_gtk Gtk::Button
after Button

If you want to change defer determining the behavior of a ruby object
until sometime after it's instantiated, there are better ways to do it
than changing the class.

1) As others have pointed out you can have the original object
delegate to a reall implementation obuect perhaps using delegator or
forwardable from the standard library.

2) You can treat the original class of the object as a superclass, and
add the particular behavior either by adding singleton methods, or by
mixing one or more modules into the instance using the Object#extend
method.

The second approach might seem cooler and might perform slightly
better although if you want to change the behavior more than once it
can more be problematical than when using the first.
 
M

Marc Heiler

I think i will go with evil.rb, at least digging into it as much as
possible.

I rather want to try and adjust the code to my thinking, not the other
way around by "delegating" or adding complexity to it, when I just want
to keep it simple in essence. I don't want to lie, I want to convert. ;)

Thanks.
 
S

Stefan Rusterholz

Marc said:
How can I convert my object "foobar" of "class Button"

foobar = Button.new

to become a "real" Gtk::Button for instance?

foobar = Button.new
foobar.kind_of?(Gtk::Button) # => true

How?
class Button
def initialize
extend Gtk::Button
end
end

It does not really change the class, and if your Gtk::Button is a
preexisting class it won't work (because this idea requires Gtk::Button
to be a module). But it changes the ancestry and methods of Gtk::Button
are invoked before those of Button.

HTH, regards
Stefan
 
D

David A. Black

Hi --

I think i will go with evil.rb, at least digging into it as much as
possible.

I rather want to try and adjust the code to my thinking, not the other
way around by "delegating" or adding complexity to it, when I just want
to keep it simple in essence. I don't want to lie, I want to convert. ;)

Then you're adding rather enormous complexity where the language
doesn't natively, or simply, support it. It's fine if you want to do
it, but it certainly isn't the simplest strategy.


David
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top