Waves のアーキテクチャ

まず、Waves はシンプルデザインを第一としています。

コードをコンパクトで拡張性あるものに保ちます。 Waves は1000行以下に保つようにしています。振る舞いのどんな層でも include でき、ディスパッチャはオーバライドや継承が出来ます。 Ruby のおかげです。 これは、構成からURIマッピングまで純粋なRubyを利用することを意味しています。

規約で規定値を提供しますが、規約を変更するのは簡単です。もし、 Waves のやり方を気に入ったなら、out of the box, then great, you’re done. もしそうでないなら、 合理的にカスタマイズする方法があるべきです。 主要なデザインコンポーネントはゆるく繋がっていて、ORM とコントローラのように、コントローラとビューでさえそうです。 これにより、後から新しいイノベーションを起こすのをとても簡単にします。 もっとも良い利用可能な解決策を利用してください。Waves は独自の HTTP プロセス層を持っていましたが、Rack の方が良かったので、今はRack上で動作しています。 Be thread-safe. Threads right now are passe, but they shouldn’t be. Ruby 1.9 supports native threading and Web applications are course-grained enough that threading doesn’t generally pose too many problems associated with parallel processing. Ultimately, threading may yet emerge as the fastest, most scalable way to run Ruby Web apps, as it has on most other language platforms.

The Waves Stack

Waves is runs on a state-of-the-art application stack, although remarkably it is not really tied to any single solution, except possibly Rack. That makes sense: Waves is a framework for building Web apps, and Rack is a framework for frameworks like Waves. Other than that, it depends on what application you’re building. That said, Waves does tend to favor some libraries over others, especially at this young stage of its development.

Web サーバ

Rack provides the HTTP processing engine. This provides Waves with a easy-to-configure processing pipeline, via Rack’s middleware, plus support for most major Ruby Web servers, via Rack’s handlers.

At the moment, Waves is actually hard-coded to support Mongrel as the Web server, although it is a trivial change to make the handler configurable. The main reason I haven’t done this is to make it a bit easier to provide support and because I’m relying on Mongrel’s MIME type interface at the moment, although it would be easy to “borrow” that code for use with Waves.


Sequel is the preferred ORM at the moment because it supports migrations and because it supports the use of plain old Ruby for defining queries, but it would only take minor changes to support DataMapper or other ORMs. Again, the need to be able to support these different configurations has led me to initially constrain them.

I am looking at Ambition as well, since it provides a nice Enumerable-based abstraction that is essentially ORM independent. Thus, it can be sort of like Rack – a layer that framework providers can use to enable support for virtually any database. However, that game is still early on, as are most of the ORM frameworks.

As an illustration of how flexible Waves really is, I have one Waves app running using soon-to-be-released Gem called Filebase, a file-oriented “database” that provides a lightweight alternative to using an ORM if you don’t really need one. I use it for CMS-type applications, where most of the data maps well to a file structure. Weighing in at 30 LOC, it is great for keeping the memory requirements down.


At the moment, Waves supports only two templating engines: Markaby, which given that it is actually Ruby code was a no-brainer for inclusion, and Erubis, which is useful for all those times when the structure of Markaby is a bit too much, or your not generating HTML.

I plan on adding XML Builder support for sure, but beyond that, I’ll let the developers tell me. I would imagine there will be some demand for HAML, especially for user-defined template scenarios. (Although, I’d like to get Sandbox working with Markaby towards the same end.)

クラス / モジュール ローダ

This might not seem to be a natural category for a framework application stack, but it is a surprisingly crucial area. Most, if not all the frameworks I’ve seen have sort of weak support in this area. This is unfortunate because Ruby itself provides great capabilities in this area.

Waves uses a Gem I wrote (for Waves) called Autocode, which does true code reloading. Rather than simply call load on various files, it actually first calls remove_const on all the elements that are intended to be reloaded. This completely wipes any constants or associated method definitions from memory, provided there are no references to them hanging around.

Autocode also has the ability to “autocreate” classes and modules from exemplars, which allows Waves to generate models, views, and controllers as needed, even when there is no source file associated with them. This not only saves some typing, but allows you to, in effect, add new MVC components to your application simply by running a migration.

Waves will shortly also support LiveConsole, which will allow hot-patching of production apps. The way this works is pretty simple, actually. Since your application is contained in a reloadable module (it’s reloadable, even if you don’t ever reload it), and since LiveConsole gives you a console into the running server process, you can simply call, say, Blog.reload from the console to update the running code, without ever bringing down the server. You have to do this within a server mutex, but since the code is truly reloaded, it is a pretty safe operation.

This kind of hot-patching feature used to be one of those things that distinguished enterprise software from comparable open-source projects, but no more. You can get hot patching for free with Waves.


これは Waves の範囲外です。あなたは望むどんなテストアプローチでも利用できます。 Waves はどんなアプローチも支持しません – 新しいアプリケーションを生成する際、テストとわかるように test ディレクトリさえ作りません。これは将来のリリースで ruby-debug をサポートするころに記述されるでしょう。 (今でも動作はすると思うのですが、まだ私自身が十分に試していないというだけです。)