:: Topo :: doCoding :: Linguagens de Programação :: Ruby :: MVC ::

Ramaze

Introdução

A framework Ramaze tem sido desenvolvida através da aplicação da metodologia BDD. Tem um conjunto mínimo de dependências, tanto que muitas aplicações apenas irão precisar de Ruby e Rack - além da Ramaze - para correrem. A Ramaze é construída para se manter leve e eliminar ou evitar o que não é realmente necessário.

Tem como princípios fundamentais: KISS, POLS, desenho modular, conjunto de dependências mínimo, documentação em código de elevada qualidade, desenvolvimento aberto e livre, recomendar a aplicação de BDD no desenvolvimento.

Background

Tal como descrito pelo autor: Ramaze is a simple, light and modular open-source web-framework written in Ruby. It provides several easy to understand and fully documented abstractions useful for the daily work of a pragmatic webdeveloper.

Os notáveis no projecto são: Aman Gupta, Jonathan Buch and Pistos. Michael Fellinger é o criador do projecto. Muito dos conceitos vieram da framework Nitro.

Referências

Oficiais

Artigos

Tutorials

Características

Além de ser simplista e basear-se em princípios simples, apresenta as seguintes características:

  • Agnóstica em relação ao interpretador de Ruby:
    1. MRI 1.8.x
    2. MRI 1.9.x
    3. JRuby 1.x
    4. Rubinius
  • Agnóstica em relação à library ORM a usar nos modelos:
    1. Sequel
    2. Data Mapper
    3. Active Record
    4. M4DBI
    5. Stone
  • Agnóstica em relação ao templating engine a usar nas views:
    1. Ezamar
    2. Erb
    3. Eruby
    4. Erubis
    5. Haml / Sass
    6. Liquid
    7. Markaby
    8. Remarkably
    9. Amrita / Amrita2
    10. Tenjin
    11. Nagoro
    12. XSLT
  • Agnóstica em relação ao servidor HTTP, pois tem como base o Rack.

Exploração

ToDoList

Neste tutorial encontrei alguns pequenos percalços, que aqui registo.

Quando se alterar um Controller, com o serviço em execução, não haverá refrescamento automático do código, pelo que é preciso terminar o serviço e voltar a lança-lo em execução, para que as alterações ao Controller sejam vistas pela Ramaze.

Step 2

Para que não ocorram problemas no Step 3, é preciso editar também o ficheiro model/init.rb:

model/init.rb

# Here goes your database connection and options:
 
# Here go your requires for models:
# require 'model/user'
 
require 'model/todo_list'

Step 8

Foi graças ao artigo Ramaze - first impressions que percebi que não existe nem as pastas nem o ficheiro src/element/page.rb, pelo que não consegui entender o uso do Templating Engine Ezamar.

Em alternativa, e porque existe o ficheiro view/page.xhtml, decidi adaptar e efectuei as seguintes alterações:

view/page.xhtml

<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
 
  <head>
    <title>TodoList</title>
 
    <meta http-equiv="Content-Script-Type" content="text/javascript" />
    <meta http-equiv="Content-Style-Type" content="text/css" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="expires" content="0" />
    <meta name="description" content="Description for search engines" />
    <meta name="generator" content="Ramaze #{Ramaze::VERSION}" />
    <meta name="keywords" content="Ramaze, Your own keywords" />
    <meta name="author" content="Max Mustermann" />
    <meta name="date" content="#{Time.now.iso8601}" />
 
    <style type="text/css">
      body     { margin: 2em;      }
      #content { margin-left: 2em; }
    </style>
  </head>
 
  <body>
    <h1>#{ @title }</h1>
 
    <div id="content">
      #@content
    </div>
  </body>
 
</html>

view/index.xhtml

<h1>TodoList</h1>
<a href="/new">New Task</a>
 
<?r if @tasks.empty? ?>
  No Tasks
<?r else ?>
  <ul>
    <?r @tasks.each do | title, status, toggle, delete | ?>
      <li>#{ h title }: #{ status } - [ #{ toggle } | #{ delete } ]</li>
    <?r end ?>
  </ul>
<?r end ?>

view/new.xhtml

<h1>New Task</h1>
<a href="/">Back to TodoList</a>
<form method="POST" action="create">
  Task: <input type="text" name="title" /><br />
  <input type="submit" />
</form>

Step 10

Por omissão, no ficheiro start.rb, vem já a linha:

start.rb

...
Ramaze.start :adapter => :webrick, :port => 7000

É preciso comentar essa linha, antes de experimentar iterativamente as várias possibilidade de configurar o servidor:

start.rb

...
Ramaze::Global.port = 7000

start.rb

...
Ramaze::Global.port = 7000
Ramaze::Global.adapter = :mongrel

start.rb

...
Ramaze::Global.setup do | g |
  g.port    = 7000
  g.adapter = :mongrel
end

start.rb

...
Ramaze.start :port => 7000, :adapter => :mongrel

No entanto, optei por não ter qualquer configuração, o que me permite escolher o servidor a executar e o porto onde quero que fique à espera de ligações:

start Ramaze

ramaze --adapter thin --port 7000

Considerações

Benchmarking

É importante realizar 2 benchmarkings: uma simples aplicação HelloWord que apresente, por exemplo, a data actual do sistema host; uma aplicação com Modelos, Vistas e Controladores. A primeira para realizar simples benchmarks dos servidores (Webrick, Mongrel, Thin, …) e para mais tarde servir de comparação com outras frameworks e a segunda para avaliar o impacto, fixando o servidor (por exemplo: Mongrel) dos engines para os modelos e para as vistas.

Servers

Algo surpreendente, foi receber os resultados e comprovar que o Ruby sobre Cygwin é mais rápido que o Ruby sobre Windows. No caso do Webrick chega mesmo a ser quase 2x mais rápido.

 Ruby MVC Framework - Benchmarking HelloWorld

Confirma-se, portanto, que o Webrick é 50% mais lento que o Mongrel, e que o Thin é mais rápido - se bem que marginalmente (no entanto é cerca de 25% mais rápido em Windows).

Infelizmente, não consegui instalar o Thin sobre o Cygwin, e nem é suportado pelo JRuby. Pelo que a opção mais sensata será seguir com o Mongrel, pelo menos até que se repita este benchmarking com o Evented Mongrel ou Swiftiply Mongrel.

Também importa realçar que a máquina Ubuntu, em hardware, é mais lenta que a máquina Windows - sendo ambas Core2 Duo - mas sobre a qual a Ramaze sobre Ruby consegue ser quase 2x mais rápida em qualquer servidor. No entanto, a performance em JRuby é semelhante.

Storage Engines

Para ter mais dados, que tornassem o benchmarking mais credível, decidi codificar um script para popular o storage com 5000 tasks.

A comparação será simplesmente entre Stone e Sequel com SQLite, não havendo tempo para também efectuar benchmarking com M4DBI, ActiveRecord ou DataMapper. Descobri entretanto que o Ramaze::Store é um wrapper sobre o YAML::Store, e que além disso demora imenso tempo - inaceitável - a popular o ficheiro YAML com 5000 entradas.

2009.01.30

Não consegui usar o Stone com a Ramaze. Após ter editado o model TodoList, nem consegui popular com as 5000 entradas nem consegui que a página index fosse sequer mostrada - foi-me devolvido o erro undefined method 'original' for TodoList:Class. Algo semelhante aconteceu com o autor do artigo Ramaze - first impressions continued. Como neste artigo o ORM escolhido foi o Sequel, vou então usar somente o Sequel para o benchmarking.

Depois de concluir as modificações para correr o benchmarking para 25 entradas somente com Sequel::SQLite3 consegui também modificar o código usando Ramaze::Store. Estas modificações permitiram que após serem migradas e adaptadas para Stone que este finalmente conseguisse funcionar com Ramaze quase totalmente. Não consegui, de todo, que:

  1. a pasta datastore/ com os ficheiros YAML fosse populada, com as 25 entradas.
  2. que após inserir nova entrada, com sucesso, e validar que o estado alterna, com sucesso entre open e close, também fosse possível apagar a entrada. Na realidade, é apagada do storage, mas o array de @tasks no método index() do MainController continua sempre populado com todas as entradas. Ou é um erro do Stone, ou falta-me ainda resolver essa funcionalidade no MainController.

No entanto, consegui os benchmarks necessários:

  • Desta vez o Ruby sobre Windows foi mais rápido do que o Ruby sobre Cygwin quando se usa Ramaze::Store:
    • Cygwin: 37.54
    • Windows: 47.65
  • Mas voltou a repetir-se o Ruby sobre Cygwin ser mais rápido que o Ruby sobre Windows quando se usa Sequel::SQLite (in-memory):
    • Cygwin: 56.54
    • Windows: 39.46

Importa realçar que enquanto que o Cygwin tem quase o dobro da performance com Sequel do que Ramaze::Store, em Windows ambos conseguem processar o mesmo número de requests por segundo, relativamente.

Nem o Ramaze::Store nem o Sequel::SQLite puderam ser usados com o JRuby. O primeiro porque aparentemente o core YAML::Store não é suportado e o segundo porque será preciso adaptar o código do modelo para usar JDBC (com H2).

Templating Engines

 
docoding/languages/ruby/mvc/ramaze.txt · Modificado em: 2009/02/07 00:40 por straider     Voltar ao topo