Ruby has ruined my C++

T

tony summerfelt

Kero wrote on 7/17/2005 6:05 PM:
and in Ruby/Tk you do:

b = TkButton.new(nil, "text"=>"quit").pack
b.command { exit }
I fail to see what you're trying to argue here...

ease.

if the first line were:

b=TkButton.new(text=>"quit").pack

i'd be a lot happier. i realize that tk has to be shoehorned into
ruby's oo'ness.

ignore me. could be i'm just frustrated at trying to recreate my own
interface (tkblog) in ruby :)
 
D

Devin Mullins

Lothar said:
Sorry but this is not true.

WxWindows never did this. It has an event table to dispatch events
to handlers methods.
Ah. You are correct. It's been a while. My mistake. You don't have to,
but it's often the easiest way to add handler methods, child windows,
etc. and is littered in all their examples. At the very least, you have
to subclass and override a couple of methods from wxApp, but I also
remember subclassing wxFrame and wxPanel. You are correct, though, in
that I never subclassed wxButton.
Of couse you can do it with every toolkit but it nowhere the
recommended programming style and there are good reasons for it.
No opinion one way or another.

Devin
 
J

Joe Van Dyk

Hello tony,
=20
ts> in tcl/tk you can use this to create a button
=20
ts> button .b -text "quit" -command {exit}
ts> pack .b
=20
ts> i'd really like something like this for ruby (off the top of my head)= :
=20
ts> class quit_button < button
=20
ts> def initalize
ts> button_text("quit")
ts> self.show
ts> placeongrid()
ts> # you get the idea
ts> end
=20
ts> def button_text(t)
ts> quit_text=3Dt
ts> end
=20
ts> def click
ts> app.cleanup
ts> end
ts> end
=20
Inheritance just for the purpose to add callbacks/configuration
already proved to be wrong a long time ago. The only framework which
tried this was self, but as self is OO without classes it's not
comparable.
=20
From the length of your example you should see where the problem is.

It is? Most ruby-gnome2 and gtkmm (c++ interface to gtk) examples use
inheritance.

I generally try to use composition instead, but it's sometimes a lot
simpler to use inheritance, especially if it's just a quick
application.
 
J

Joe Van Dyk

Kero wrote on 7/17/2005 6:05 PM:
=20
=20
ease.
=20
if the first line were:
=20
b=3DTkButton.new(text=3D>"quit").pack

You could do:
b =3D TkButton.new(nil, :text =3D> "quit").pack

I'm not sure if you can use nil there though... doesn't it need a parent?
 
L

Lothar Scholz

Hello tony,

ts> mathew wrote on 7/18/2005 12:30 PM:


ts> clicking on the 'last 90 days' i get: May 7, 2005 for the last update

ts> ouch.

ts> seeing as arachno-ruby uses fxruby, and i've been fairly impressed
ts> with that ide, i'm probably going to lean towards that...

No ArachnoRuby uses FOX not FXRuby. I've written and modified a
lot of the original FOX widgets.

You can also modify widgets with fxruby but it is sometimes
more trouble to do it with ruby and it can result in bad performance
if you do it in a simple, non optimized way. Drawing and
layout calculation can take a serious amount of pure ruby instructions
(integer operations and function calls through a lot of wrappers)
which might be factor 100x slower then C.

And for wxruby: I wouldn't give to much attention to the last update
date. Whats important is how the CVS changed over the last 3 month.
If there are no improvements it's a clear sign of a problem.
 
D

Daniel Amelang

Let's say that I have this...friend...um yea. And this 'friend' was
tossing around ideas about what a rubyesque GUI toolkit API would look
like. What would people think of something like this for event
handling?:

...
button.when_pushed do
puts "Hey, don't push my buttons!"
end
...

Dan
 
J

Jacob Fugal

Let's say that I have this...friend...um yea. And this 'friend' was
tossing around ideas about what a rubyesque GUI toolkit API would look
like. What would people think of something like this for event
handling?:
=20
...
button.when_pushed do
puts "Hey, don't push my buttons!"
end
...

I, personally, would prefer something more along the lines:

button.on_event( :push ) do
puts "Hey, don't push my buttons!"
end

I happen to have the same "friend", though I notice he's been in a
coma while his alter ego has been busy with life, marriage and such.
:)

Jacob Fugal
 
D

Daniel Amelang

So, tell my why you prefer the on_event( :event_type ) syntax?

I prefer the when_pushed syntax because of the readablity and
abstraction of events altogether. 'button when pushed do this' feels
very natural. But maybe it feels very unnatural for others. 'button on
event push' is OK with me, it's the fxRuby way after all.

The when_pushed method would actually (via the magic of method missing
possibly) translate to something like register_handler :)push, block)
under the hood.

Dan
 
T

tony summerfelt

Lothar Scholz wrote on 7/18/2005 4:47 PM:
No ArachnoRuby uses FOX not FXRuby. I've written and modified a
lot of the original FOX widgets.

yes,that's what i meant...as you can tell i've been jumping back and
forth between gui toolkits :)
 
J

Jacob Fugal

So, tell my why you prefer the on_event( :event_type ) syntax?
=20
I prefer the when_pushed syntax because of the readablity and
abstraction of events altogether. 'button when pushed do this' feels
very natural. But maybe it feels very unnatural for others. 'button on
event push' is OK with me, it's the fxRuby way after all.
=20
The when_pushed method would actually (via the magic of method missing
possibly) translate to something like register_handler :)push, block)
under the hood.

I don't know, it's just preference. :) Your syntax is a good
alternative. But I'll take a stab at explaining my preference
anyway...

I think the main difference is the conciseness of the grammar style,
and an easier reflection between event handling and event generation.
For one thing, the 'when_pushed' variant would need a translation in
method_missing to turn 'pushed' into :push. The 'on_*' route doesn't
necessarily preclude method_missing abstraction either:

module EventListener
def register_handler( event_name, &action )
@actions ||=3D {}
@actions[event_name] ||=3D []
@actions[event_name] << action
end
def handle_event( event_name )
if @actions[event_name]
@actions[event_name].each { |action| action[self] }
end
end
def method_missing( symbol, *args, &block )
if /^on_/.match( symbol )
self.register_handler( symbol.to_s.gsub(/^on_/, '').to_sym, *args ) &=
block
else
self.handle_event( symbol )
end
end =20
end

class Button
include EventListener
end

button =3D Button.new
button.on_push do |b|
puts "Don't push my buttons!"
end

button.push
 
D

Daniel Amelang

Ha! You've reproduced my code almost exactly :)

I'd like to hear what other people have to say about this approach,
but I'm afraid that we're the only ones left still reading this
thread.
=20
Dan
 
K

Kero

Ha! You've reproduced my code almost exactly :)
I'd like to hear what other people have to say about this approach,
but I'm afraid that we're the only ones left still reading this
thread.

Nah, I'm still here.

Button.new("exit") { exit }

I don't care who handles the event when and how or even what it is
called. I want the toolkit to take care of that *entirely*.
asynchronously, threadsafe.

Note that this is somewhat confusing with the lacking parent widget,
which is a container and could use a block as layout definer (meaning
some blocks are executed at initialize() and some on an external
event). Once more, look up EasyGtk discussions.

VBox.new("window title") { |w|
Canvas.new() { ... }
Button.new("Close") {
w.close
}
}

and variations like

vbox { |v|
canvas { ... }
button("Close") { v.close }
}

another confusing item is that there are only 'default' parameters
given, even tho you can come up with various ways to specify
'non-default' parameters (font, border width, how to layout in detail
in the vbox).

+--- Kero ------------------------- kero@chello@nl ---+
| all the meaningless and empty words I spoke |
| Promises -- The Cranberries |
+--- M38c --- http://members.chello.nl/k.vangelder ---+
 
J

Jacob Fugal

Button.new("exit") { exit }
=20
I don't care who handles the event when and how or even what it is
called. I want the toolkit to take care of that *entirely*.
asynchronously, threadsafe.

That is interesting and makes for a very simple interface when you
want a quick and dirty gui. However, this doesn't work very well when
there's more than one possible event on a widget. For instance, you
might have a custom widget to which you want to add both on_hover and
on_click actions.

Jacob Fugal
 
K

Kero

Button.new("exit") { exit }
That is interesting and makes for a very simple interface when you
want a quick and dirty gui. However, this doesn't work very well when
there's more than one possible event on a widget. For instance, you
might have a custom widget to which you want to add both on_hover and
on_click actions.

Then use the complexer registration method for that.
Simple things do not disable complex things.

+--- Kero ------------------------- kero@chello@nl ---+
| all the meaningless and empty words I spoke |
| Promises -- The Cranberries |
+--- M38c --- http://members.chello.nl/k.vangelder ---+
 
M

Michal 'hramrach' Suchanek

I, personally, would prefer something more along the lines:

button.on_event( :push ) do
puts "Hey, don't push my buttons!"
end

This looks like it is more flexible .. but it requires the user of the
library to write a dispatcher function. And since ruby is dynamic you do
not need to force users into writing dispatchers to get flexibility.

So I like the first one better.

Thanks

Michal Suchanek
 
M

Michal 'hramrach' Suchanek

This looks like it is more flexible .. but it requires the user of the
library to write a dispatcher function. And since ruby is dynamic you do
not need to force users into writing dispatchers to get flexibility.

err, no. I am completely confused this time.
 
J

Jacob Fugal

=20
This looks like it is more flexible .. but it requires the user of the
library to write a dispatcher function. And since ruby is dynamic you do
not need to force users into writing dispatchers to get flexibility.

First, the user doesn't have to write the dispatcher, that's provided
by the library. You mention in a followup that you were confused, so
I'll forgive you for that ;) I know I get confused quite often :)

However, you do bring up a good point: since ruby is dynamic you
shouldn't need to write dispatchers. Why can't I just do this:

class MyButton < Button
# override what happens on a push, then simply have windowing code
# call methods, rather than sending events
def push
puts "Don't push my buttons!"
end
end

button =3D MyButton.new
button.push

First off, as has been mentioned in another thread, inheritance just
to define new events isn't really the best idea. Ok, easy to fix:

button =3D Button.new
class << button
def push
puts "Don't push my buttons!"
end
end
button.push

We could even wrap that in a method to make the syntax cleaner. With a
clean syntax, we can even switch out what the actions are based on
runtime times without ugliness. Looking good. But there are still two
more objections which lead me to suggest a dispatcher model: shared
actions and multiple actions tied to the same event. Neither of these
work very well if at all without a stored proc/dispatch model.

Jacob Fugal
 
D

Daniel Amelang

Again, someone has stolen a page out of my current code. :) At least
it means that I wasn't insane to think it up. Either that, or there
are two insane people here...

More opinions, please? Where is Lothar? He's one of the most
experienced in GUI toolkits...

Dan
 
D

Daniel Amelang

We could even wrap that in a method to make the syntax cleaner. With a
clean syntax, we can even switch out what the actions are based on
runtime times without ugliness. Looking good. But there are still two
more objections which lead me to suggest a dispatcher model: shared
actions and multiple actions tied to the same event. Neither of these
work very well if at all without a stored proc/dispatch model.

+1000 Yes! I spent _months_ playing with the 'dispatch directly
through method' approach and came to the same conclusion for the same
reasons. It is very 'cool', but becomes inflexible very quickly. I
guess with AOP techniques, you could get the multiple action thing,
but it's just not as easy and how are you going to delete actions
easily? Reorder? Ug.

Right now I'm playing with a publish-subscribe model for
communicating between widgets. In this scenario, system events,
inter-widget events and direct events (calling button.push explicitly)
are all just messages handled by a very small pubsub core contained in
each widget. Essencially, just a fancy dispatcher :)

Dan
 

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,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top