Wee web-framework. It's great!

J

Joao Pedrosa

Hi,

For the last couple of days I've been deepening my knowledge of Wee.
From the point of view of a programmer (not a designer, which I'm
not), Wee is awesome. I still need to workout a full example, but Wee
has been behaving the way I expect, so I wanted to say a *thank you*
to Michael for creating a truly gem. I know that the entry barrier is
not easy (not as compared to Rails,) but it's worth it. At least you
will come to know a different way of building web-applications.

Wee is Ruby in both senses. :) It has a default O/R mapper (Og) and
scaffolding ala Rails. Wee is OO and has its own magic, thanks to its
inheritance (Seaside,) so thanks Avi Bryant, author of Seaside, for
his creativity and for lending a hand to Michael.

I hope Wee will keep improving and become a major player just like
Rails and Seaside. :)

I think I have found what I was after (for the web) since I started using Ruby.

Cheers,
Joao
 
D

Dema

Joao,

I am really curious about continuation-based web frameworks. Can you
give us some examples in how this kind of web development can be
different/better than what is done with a more "standard" framework
such as Rails ?

Rgds
 
V

Vincent Foley

You know, I think Wee could become really hot if someone could mix it
with ActiveRecord.
 
J

jason_watkins

My immediate thought as well upon watching those wee video's linked the
other day.
 
S

Shalev NessAiver

What do you mean by "continuation-based" framework? Does that indicate
some sort
of persistent object that is kept alive throughout an entire user
session (just a wild guess)?

-Shalev
 
J

Joao Pedrosa

Hi,
I am really curious about continuation-based web frameworks. Can you
give us some examples in how this kind of web development can be
different/better than what is done with a more "standard" framework
such as Rails ?

Wee does not need continuations to work, which is a good thing because
sometimes they provoke some memory leaks in Ruby, mainly when things
get complex. I really don't know much about continuations myself. I
know that Wee at first used continuations, but since then it has
become only an option, which I'm not wanting to use at the moment. :)
I suppose that it can make somethings more automatic, which is a good
thing, but Michael has probably created some nice workarounds for Wee
to work without continuations. Great creativity of him and great job.

GUI is generally divided in components/widgets, right? The problem is
that in the web, GUI components happen to exist in the browser
(client), but most of the business logic and state comes from the
server. In a normal web-page, you may have more than a FORM tag. So
when one is submitted, you may lose what has been entered in another
FORM. You may need to handle the BACK browser button. And you may need
to handle the Session, that is the maintenance of the state between
browser requests. Now, imagine arbitrary GUI components that happen to
be in the same web-page. Imagine each component with its own state and
responding to events. That's a lot to imagine, but have no fear,
because Wee is here.

Wee supports the GUI componentization for a web-app. You no longer
need to worry about everything by yourself (mainly about keeping
everything in sync), because Wee can handle a lot by itself. Not only
that, but the HTML generation is nice ruby code, with closures,
blocks, etc. The components will work together in the same page or in
different pages. Unload your work to them, and they will handle it.
You no longer need to worry about URLs, for instance. Just
"call(Component.new)" and it's like going to the next page. Just
"answer" and the previous component takes care.

Most of the layout work should be handled by CSS and JavaScript,
anyway. So the only HTML that's going to be generated by Wee is the
minimum necessary.

A lot of this happens by "magic". Sometimes you need to direct Wee to
do the right thing, because resources are limited so it's better to
share the responsibility of the resource handling with the developer.
For example, when handling the BACK button, I think (maybe because of
the lack of continuation issue.)

Wee has less layers than Rails, so it should be faster when working on
WEBrick. Wee is smaller than Rails, also. And lastly, I needed a
web-framework for some persistence library that I've created, and it
seems that Wee is a perfect match for it, so I couldn't be happier.
:) In the future I might release it, but it's not an O/R mapper so
Og, which is an O/R mapper, already fills this role.

This is my unofficial description of what I've gathered of Wee at the
moment. It may be even better than this. It may become even better. It
has a bright future, that's for sure.

Rails is great also.

Cheers,
Joao
 
M

Michael Neumann

Vincent said:
You know, I think Wee could become really hot if someone could mix it
with ActiveRecord.

That's *very* simple to do. But note that you can already use Wee with
Og, another O-R mapping library (which I like more, as I don't have to
create the SQL myself... and I don't have a graphical SQL editor).

If there's lots of interest, I might implement an ActiveRecord
scaffolder for Wee. But first, try Og ;-)


Regards,

Michael
 
Z

Zach Dennis

Michael said:
If there's lots of interest, I might implement an ActiveRecord
scaffolder for Wee. But first, try Og ;-)

Is it pronounced, "Ohhhgggg" or "Oh - G"?

Zach
 
M

Michael Neumann

Dema said:
Joao,

I am really curious about continuation-based web frameworks. Can you
give us some examples in how this kind of web development can be
different/better than what is done with a more "standard" framework
such as Rails ?

In short, you can write web-applications as you would write normal (e.g.
console) applications. This is not easily possible in Rails (or in Wee
without continuations).

Consider this method:

def checkout
billing = getAddress("Billing Address")
if useSeparateShippingAddress()
shipping = getAddress("Shipping Address")
else
shipping = billing
end
payment = getPaymentInfo()
showConfirmation(billing, shipping, payment)
end

Here, getAddress() displays a new page where you can enter your billing
address and returns an Address object. The same for
useSeparateShippingAddress(), which would ask whether you want to use a
separate shipping address and so on.

Try to write this without continuations, you end up in something like:

def checkout
call getAddress("Billing Address"), :gotAddress
end

def gotAddress(address)
call useSeparateShippingAddress(), :sep
end

def sep(use_sep)
if use_sep
call ...
else
...
end
end

It gets overly complex. It's (only) a little bit better if you use blocks:

def checkout
call getAddress("Billing Address") {|billing|
...
}
end

But note that you have to use #call instead of a regular method call.
#call requires a component as argument.

Hope this helps a little bit in understanding the advantage of
continuations. Continuations might be unimportant for lots of
applications, for others they are really great.

Regards,

Michael
 
M

Michael Neumann

Joao said:
Hi,




Wee does not need continuations to work, which is a good thing because
sometimes they provoke some memory leaks in Ruby, mainly when things
get complex. I really don't know much about continuations myself. I
know that Wee at first used continuations, but since then it has

Not quite right ;-)
Wee was developed without continuations from day one. Then, in a
discussion with Avi, I realized how nice continuations are (for some
kind of applications). So I added them (that was ~ 30 lines of code ;-).
GUI is generally divided in components/widgets, right? The problem is
that in the web, GUI components happen to exist in the browser
(client), but most of the business logic and state comes from the
server. In a normal web-page, you may have more than a FORM tag. So
when one is submitted, you may lose what has been entered in another
FORM. You may need to handle the BACK browser button. And you may need
to handle the Session, that is the maintenance of the state between
browser requests. Now, imagine arbitrary GUI components that happen to
be in the same web-page. Imagine each component with its own state and
responding to events. That's a lot to imagine, but have no fear,
because Wee is here.

Wee supports the GUI componentization for a web-app. You no longer
need to worry about everything by yourself (mainly about keeping
everything in sync), because Wee can handle a lot by itself. Not only
that, but the HTML generation is nice ruby code, with closures,
blocks, etc. The components will work together in the same page or in
different pages. Unload your work to them, and they will handle it.
You no longer need to worry about URLs, for instance. Just
"call(Component.new)" and it's like going to the next page. Just
"answer" and the previous component takes care.

If you call a component, this will replace the calling component with
the called component until the called component answers.

As a page in Wee consists usually of multiple components, this can
happen at different places simultaneously. For example, you have a
IntegerField component, which lets you enter integer values into an
input field. If you enter a wrong value (say: "123f", which is not an
integer), this component might display an ErrorMessageBox component
instead of itself, which tells the user about the faulty input. If the
users clicks that message box away, the original IntegerField component
is displayed. The rest of the page stays the same all of the time
(unless you click on other "parts" of the page while the message box is
displayed).
Most of the layout work should be handled by CSS and JavaScript,
anyway. So the only HTML that's going to be generated by Wee is the
minimum necessary.

A lot of this happens by "magic". Sometimes you need to direct Wee to
do the right thing, because resources are limited so it's better to
share the responsibility of the resource handling with the developer.
For example, when handling the BACK button, I think (maybe because of
the lack of continuation issue.)

I don't understand you here. Could you please try to explain again.

Maybe: As there is only one component(-tree) per session, you have to
take snapshots of those values that you want to be back-trackable, so
that you can view older states of the page.
Wee has less layers than Rails, so it should be faster when working on

Hmm, I don't know too much about Rails, but Wee will probably be slower
as there are multiple phases and you usually have a component-tree
instead of just one "controller/view". This component-tree is traversed
two times, once to invoke callbacks and another time for rendering the
html. And then, the html-renderer is probably slower than ERb, but then
you're not limited to use the programmatic rendering approach, you can
use whatever you like to generate the HTML.
WEBrick. Wee is smaller than Rails, also. And lastly, I needed a
web-framework for some persistence library that I've created, and it
seems that Wee is a perfect match for it, so I couldn't be happier.
:) In the future I might release it, but it's not an O/R mapper so
Og, which is an O/R mapper, already fills this role.

This is my unofficial description of what I've gathered of Wee at the
moment. It may be even better than this. It may become even better. It
has a bright future, that's for sure.

Thank you very much for this nice description. Very helpful!

Regards,

Michael
 
G

George Moschovitis

Is it pronounced, "Ohhhgggg" or "Oh - G"?
I pronounce it Ogg (like Egg with a leading O ;-).

Note sure if that's right...

Hmm, I pronnounce it 'Ohh G' but Ogg sounds nice too :)

George
 
M

Michael Neumann

George said:
Hmm, I pronnounce it 'Ohh G' but Ogg sounds nice too :)

Ooops. But there is already Ogg-Vorbis... well, I would simply pronounce
it ObjectGraph ;-)

Regards,

Michael
 
G

George Moschovitis

Hmm, I pronnounce it 'Ohh G' but Ogg sounds nice too :)
Ooops. But there is already Ogg-Vorbis... well, I would simply pronounce
it ObjectGraph ;-)

Nope, Og sounds cooler, and I have this oohh-soo-nice og-logo :)

George.
 
J

Joao Pedrosa

Hi,
Not quite right ;-)
Wee was developed without continuations from day one. Then, in a
discussion with Avi, I realized how nice continuations are (for some
kind of applications). So I added them (that was ~ 30 lines of code ;-).

I stand corrected. :) Thanks for jumping in.
If you call a component, this will replace the calling component with
the called component until the called component answers.

As a page in Wee consists usually of multiple components, this can
happen at different places simultaneously. For example, you have a
IntegerField component, which lets you enter integer values into an
input field. If you enter a wrong value (say: "123f", which is not an
integer), this component might display an ErrorMessageBox component
instead of itself, which tells the user about the faulty input. If the
users clicks that message box away, the original IntegerField component
is displayed. The rest of the page stays the same all of the time
(unless you click on other "parts" of the page while the message box is
displayed).
Yes!

I don't understand you here. Could you please try to explain again.

Maybe: As there is only one component(-tree) per session, you have to
take snapshots of those values that you want to be back-trackable, so
that you can view older states of the page.

That's it. But _I_ know what you are talking about. People should give
Wee a try. :)
Hmm, I don't know too much about Rails, but Wee will probably be slower
as there are multiple phases and you usually have a component-tree
instead of just one "controller/view". This component-tree is traversed
two times, once to invoke callbacks and another time for rendering the
html. And then, the html-renderer is probably slower than ERb, but then
you're not limited to use the programmatic rendering approach, you can
use whatever you like to generate the HTML.

I'm not really into benchmarks. It was just a general feeling after
running the Apache "ab" command a couple of times.
Thank you very much for this nice description. Very helpful!

Thank you for creating Wee. :)

Cheers,
Joao
 
J

Joao Pedrosa

Hi,

I think it's important to say that the dynamic nature of Ruby
contributes to a nice development environment for Wee, that is,
whenever we are editing one of the components, and we save it, Wee
tries to reload it. If it had to be compiled it would slow this cycle
a little bit. And worse, because the compiler would complain at the
first sign of incorrectness, making errors appear when we surely new
that the component was not ready yet for compilation. Behind the
scenes, Wee remaps methods and creates components only when it's
necessary (time saving feature!)

It makes it appear that I'm editing an HTML and not a Ruby file.
That's it! Lovely.

Actually, it has less to do with editing an HTML and more with
creating the business logic of our application. The HTML is generated
automagically for us.

Look at this:

r.text_input.callback{|v| do_something_with v}.value(@original_value)

That's all that's needed to create the INPUT TYPE=TEXT object and at
the same time fill it with the default value and save its returning
value.

Add a submit button to it and you have your FORM.

r.submit_button.callback{save_edition}.value('Save Edition')

That's how everything is created, generally. There is more to it,
because it needs to support the simple and the complex, so it
"scales."

I hope you will give Wee a try. No, not many web-frameworks that work like this.

Cheers,
Joao
 
M

Michael Neumann

Joao said:
Hi,

I think it's important to say that the dynamic nature of Ruby
contributes to a nice development environment for Wee, that is,
whenever we are editing one of the components, and we save it, Wee
tries to reload it. If it had to be compiled it would slow this cycle
a little bit. And worse, because the compiler would complain at the
first sign of incorrectness, making errors appear when we surely new
that the component was not ready yet for compilation. Behind the
scenes, Wee remaps methods and creates components only when it's
necessary (time saving feature!)

It makes it appear that I'm editing an HTML and not a Ruby file.
That's it! Lovely.

Actually, it has less to do with editing an HTML and more with
creating the business logic of our application. The HTML is generated
automagically for us.

Look at this:

r.text_input.callback{|v| do_something_with v}.value(@original_value)

And for assigning it back to @original_value one can use this short-cut:

r.text_input.callback{|@original_value|}.value(@original_value)

Yeah, this looks ugly ;-)

Or alternativly without the need to create a block:

r.text_input.callback:)instance_variable_set, :eek:riginal_value)
That's all that's needed to create the INPUT TYPE=TEXT object and at
the same time fill it with the default value and save its returning
value.

Add a submit button to it and you have your FORM.

r.submit_button.callback{save_edition}.value('Save Edition')

That's how everything is created, generally. There is more to it,
because it needs to support the simple and the complex, so it
"scales."

Just want to add, that this is only *one way* to generate HTML in Wee.
You can use other renderers simply by overwriting method #renderer_class
of your component class. Or you could use ERb-templates directly:

# c.rb
class MyComponent < Wee::Component
template :render
end

# c.tpl
<ul>
<% (1..10).each do |i| %>
<li><%= i %></li>
<% end %>
</ul>

You can even define "block"-templates (this of course is a bad example,
as templates do not accept parameters):

# c.rb
class MyComponent < Wee::Component
template :render
tempalte :render_item
end

# c.tpl
<ul>
<% (1..10).each do |@i| %>
<% render_item %>
<% end %>
</ul>

# c.tpl-item
<li><%= @i %></li>

Or you can mix templates with programmatic html generation:

# c.rb
class MyComponent < Wee::Component
template :render

def render_item(i)
r.li.with(i)
end
end

# c.tpl
<ul>
<% (1..10).each do |i| %>
<% render_item(i) %>
<% end %>
</ul>

Regards,

Michael
 

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

Forum statistics

Threads
474,169
Messages
2,570,915
Members
47,456
Latest member
JavierWalp

Latest Threads

Top