[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

concurrent input from GUI *and * from irb

Joachim Wuttke

9/4/2006 10:37:00 AM

I am currently redesigning a program that shall accept input
from both a GUI and from a terminal window that runs irb.

In reaction to the input, some output will be written to the
terminal or/and some controls in the GUI will change.

I need help on the basic architecture of such a system.
I have two rather vague ideas:

(1) Somehow run the irb terminal within the GUI's event loop?

(2) One thread runs the GUI, one thread runs the terminal?

Any comment will be appreciated, Joachim

10 Answers

Kero van Gelder

9/4/2006 1:36:00 PM

0

> I am currently redesigning a program that shall accept input
> from both a GUI and from a terminal window that runs irb.
>
> In reaction to the input, some output will be written to the
> terminal or/and some controls in the GUI will change.
>
> I need help on the basic architecture of such a system.
> I have two rather vague ideas:
>
> (1) Somehow run the irb terminal within the GUI's event loop?

Some toolkits provide for actions-when-idle ("idle" is the keyword for at
least one of them) or perform-this-action-after-that-delay.

*nix only (I don't know how M$ and Mac/cocoa behave in this regard):

The main PITA with GUI threads is that they think that they are the main
program. From that "design", it follows that those threads tend to block
natively when waiting for input, thus blocking all other Ruby threads. It
results in crazy constructions to embed one in the other, even without Ruby
in between, including an X11 extension that shouldn't have been (passing
focus from one toolkit to another).

irb uses readline; readline has a similar problem.

> (2) One thread runs the GUI, one thread runs the terminal?

(3) One program irb, one GUI, both talk with drb to the real program (which,
coincidentally, has a nice mutex somewhere to protect it from race conditions).

(4) Use a multi-line text widget to emulate irb

benjohn

9/4/2006 2:15:00 PM

0

> I am currently redesigning a program that shall accept input
> from both a GUI and from a terminal window that runs irb.
>
> In reaction to the input, some output will be written to the
> terminal or/and some controls in the GUI will change.
>
> I need help on the basic architecture of such a system.

Do you know the model view controller design pattern? Also look at
tiered designs where persistence is at the bottom, business logic is on
top of this, and "presentation" is on top of the "business logic".

If you factor out your models and the kinds of changes that it's
possible to make to your system, you should be able to quite cleanly
place a GUI and a command line "presentation" of the underlying system
in to a seperate module. In fact, you should be able to bolt on
arbitrary presentations (web based too, say) without too much trouble :)

You'll probably want some kind of concept of transactions and
synchronisation in the model to allow for different active parties to
make concurrent changes.

Cheers,
Benjohn


Paul Lutus

9/4/2006 4:20:00 PM

0

Joachim (München) wrote:

> I am currently redesigning a program that shall accept input
> from both a GUI and from a terminal window that runs irb.
>
> In reaction to the input, some output will be written to the
> terminal or/and some controls in the GUI will change.
>
> I need help on the basic architecture of such a system.
> I have two rather vague ideas:
>
> (1) Somehow run the irb terminal within the GUI's event loop?
>
> (2) One thread runs the GUI, one thread runs the terminal?

IMHO you are better off writing a GUI that handles events from both the GUI
controls and the terminal window in a single thread. I say this for several
reasons. One is that Ruby threads within a single process aren't as
independent of each other as one might expect based on other languages --
indeed, IMHO the present Ruby thread facility is not very good. Another is
that multiple threads may represent a case of premature optimization,
before the simpler arrangement has been tried.

Does the irb terminal window accept input from a user, or is it fed data
from the program itself? If the former, it is highly likely that a
single-thread, user-event model would be best. Imagine a text editor
application, with a window for text entries and a set of controls and
menus. The user can type in the window or press buttons. There's no need
for multiple threads in this case.

Also, instead of using irb, have you considered using Kernel::eval? You
might get better results and more control using eval and similar processing
options than by running a copy of irb. This of course depends on the
purpose of your program, which you haven't discussed.

--
Paul Lutus
http://www.ara...

Joachim Wuttke

9/5/2006 8:55:00 AM

0

Thank you, Kero and Paul, for your comments.

I see that I have to supply more specific information about my
application.

It's for scientific data analysis. The expert user will do most work
through
a dialog interface which I want to re-implement by extending irb.
Commands
entered through the irb terminal will result in changes in diagrams or
tables that run in separate GUI windows; mouse clicks in these windows
shall have the same effect as specific terminal commands. I also need a
log file which keeps track of all activities.

In conclusion, GUI activity should produce a command string which is to
be
executed by irb, and some irb commands will result in GUI changes.

Your comments indicate that threads are no good idea.

Is there no simpler solution than running irb and GUI as separate
processes,
with lots of interprocess communication?

Thanks again, Joachim

Paul Lutus

9/5/2006 9:39:00 AM

0

Joachim (München) wrote:

/ ...

> Is there no simpler solution than running irb and GUI as separate
> processes,
> with lots of interprocess communication?

Well, the answer depends on what kinds of commands you want to run. Again,
will Kernel::eval produce the desired outputs? I ask because running irb
and feeding it commands may be a bit tricky.

Using Kernel::eval, you could pose and get rather sophisticated results with
single calls and responses, thus simplifying the required interaction.
Another approach is to create a Ruby script on the fly, execute it and
capture the output.

--
Paul Lutus
http://www.ara...

Joachim Wuttke

9/5/2006 2:10:00 PM

0

my user should be able to define variables, to define functions, to
include scripts, to hack for-loops, to iterate over arrays &c: the full
functionality of irb. Is that really possible with Kernel::eval ?
Joachim

Logan Capaldo

9/5/2006 2:17:00 PM

0


On Sep 5, 2006, at 10:10 AM, Joachim (München) wrote:

> my user should be able to define variables, to define functions, to
> include scripts, to hack for-loops, to iterate over arrays &c: the
> full
> functionality of irb. Is that really possible with Kernel::eval ?
> Joachim
>
>

Of course it is. irb is built on top of eval. (irb is AFAIK, pure
ruby. Without eval it wouldn't work at all.)


M. Pehle

9/5/2006 3:36:00 PM

0

Joachim (München) schrieb:
> my user should be able to define variables, to define functions, to
> include scripts, to hack for-loops, to iterate over arrays &c: the full
> functionality of irb. Is that really possible with Kernel::eval ?
> Joachim
>

engl.: have a look on how fxri is dealing with that problem. there you
have an IRB integrated within a Fox GUI. i think it would be possible to
manipulate the GUI with its own IRB :) you also can run the fxirb.rb
from the fxri lib directory as a standalone. i also tried to write a
piece of code that has a command line like the DOS prompt and a GUI. i
used tk and got problems because of tk's need to be the main thread.
then i tried to write a version, where the single elements of the
program talk to a drb-server (ok, the GUI was the server (: ), but it is
not really nice to deal with.

ger.: guck dir mal an, wie fxri mit dem problem umgeht. dort ist die IRB
in einer Fox-GUI integriert. ich denke, es sollte sogar möglich sein,
die GUI mit ihrer eigenen IRB zu manipulieren :) du kannst die fxirb.rb
aus dem fxri-lib-verzeichnis auch eigenständig ausführen. ich hab auch
mal versucht, ein bisschen code zu schreiben, um kommandozeile und GUI
zu haben. ich hab tk benutzt und bekam probleme damit, dass tk immer
meint, der main-thread sein zu wollen. dann hab ich versucht, eine
version zu schreiben, bei der die einzelnen elemente des programms mit
einem drb-server kommunizieren (ok, die GUI war der server (: ), aber
damit lässt sich nicht besondern angenehm umgehen.

Mario (Berlin)

Ken Bloom

9/6/2006 2:46:00 PM

0

On Tue, 05 Sep 2006 07:09:55 -0700, Joachim (München)
wrote:

> my user should be able to define variables, to define functions, to
> include scripts, to hack for-loops, to iterate over arrays &c: the full
> functionality of irb. Is that really possible with Kernel::eval ?
> Joachim

Yes, just like some of the examples that float around here of people
defining whole methods in class_eval (sometimes several methods, in fact)
you can indeed do that. (And I just tested and you can load/require files
too)

Be aware though that by using Kernel::eval on user input, your user can
also sleuth around and hack his way into the program you have written, so
you should be very careful about using this anywhere were security is
critical.

You should also be very careful about running eval in a context where
there are exposed functions that could interfere with your user's intended
meaning for his code.

I'd suggest looking at how IRB works, and then replicate its guts to
provide a relatively safe and clean execution environment. (Or use parts
of the IRB setup, but not the front command shell.) In particular, I think
the tricks are in irb/workspace.rb

--Ken Bloom

--
Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu...

Paul Lutus

9/6/2006 3:40:00 PM

0

Joachim (München) wrote:

> my user should be able to define variables, to define functions, to
> include scripts, to hack for-loops, to iterate over arrays &c: the full
> functionality of irb. Is that really possible with Kernel::eval ?

A lot of user-entered code can be packed into an "eval" entry and then
executed. A simple example:

#/usr/bin/ruby -w

eval("1.upto(12) { |y| 1.upto(12) { |x| printf(\"%4d\",x*y) }; puts \"\" }")

Output:

1 2 3 4 5 6 7 8 9 10 11 12
2 4 6 8 10 12 14 16 18 20 22 24
3 6 9 12 15 18 21 24 27 30 33 36
4 8 12 16 20 24 28 32 36 40 44 48
5 10 15 20 25 30 35 40 45 50 55 60
6 12 18 24 30 36 42 48 54 60 66 72
7 14 21 28 35 42 49 56 63 70 77 84
8 16 24 32 40 48 56 64 72 80 88 96
9 18 27 36 45 54 63 72 81 90 99 108
10 20 30 40 50 60 70 80 90 100 110 120
11 22 33 44 55 66 77 88 99 110 121 132
12 24 36 48 60 72 84 96 108 120 132 144

It is difficult to imagine an advantage to irb in this context, where the
real source of the code is, say, a GUI text editor pane, and irb's keyboard
interaction preference may be difficult to overcome.

--
Paul Lutus
http://www.ara...