<commit_before>= Sinatra
<i>Atención: Este documento es una traducción de la versión en inglés y puede estar desactualizado.</i>

Sinatra es un DSL para crear aplicaciones web rápidamente en Ruby con un mínimo
esfuerzo:

  # miapp.rb
  require 'sinatra'

  get '/' do
    'Hola mundo!'
  end

Instalá la gem y ejecutá la aplicación con:

  gem install sinatra
  ruby -rubygems miapp.rb

Podés verla en: http://localhost:4567

Es recomendable además ejecutar <tt>gem install thin</tt>, ya que Sinatra lo va
a utilizar cuando esté disponible.

== Rutas

En Sinatra, una ruta está compuesta por un método HTTP y un patrón de una URL.
Cada ruta se asocia con un bloque:

  get '/' do
    .. mostrar algo ..
  end

  post '/' do
    .. crear algo ..
  end

  put '/' do
    .. reemplazar algo ..
  end

  patch '/' do
    .. modificar algo ..
  end

  delete '/' do
    .. aniquilar algo ..
  end

  options '/' do
    .. informar algo ..
  end


Las rutas son comparadas en el orden en el que son definidas. La primer ruta
que coincide con la petición es invocada.

Los patrones de las rutas pueden incluir parámetros nombrados, accesibles a
través de el hash <tt>params</tt>:

  get '/hola/:nombre' do
    # coincide con "GET /hola/foo" y "GET /hola/bar"
    # params[:nombre] es 'foo' o 'bar'
    "Hola #{params[:nombre]}!"
  end

También podés acceder a los parámetros nombrados usando parámetros de bloque:

  get '/hola/:nombre' do |n|
    "Hola #{n}!"
  end

Los patrones de ruta también pueden incluir parámetros splat (o wildcard),
accesibles a través del arreglo <tt>params[:splat]</tt>:

  get '/decir/*/al/*' do
    # coincide con /decir/hola/al/mundo
    params[:splat] # => ["hola", "mundo"]
  end

  get '/descargar/*.*' do
    # coincide con /descargar/path/al/archivo.xml
    params[:splat] # => ["path/al/archivo", "xml"]
  end

O, con parámetros de bloque:

  get '/descargar/*.*' do |path, ext|
    [path, ext] # => ["path/al/archivo", "xml"]
  end

Rutas con Expresiones Regulares:

  get %r{/hola/([\w]+)} do
    "Hola, #{params[:captures].first}!"
  end

O con un parámetro de bloque:

  get %r{/hola/([\w]+)} do |c|
    "Hola, #{c}!"
  end

Los patrones de ruta pueden contener parámetros opcionales:

  get '/posts.?:formato?' do
    # coincide con "GET /posts" y además admite cualquier extensión, por
    # ejemplo, "GET /posts.json", "GET /posts.xml", etc.
  end

=== Condiciones

Las rutas pueden incluir una variedad de condiciones de selección, como por
ejemplo el user agent:

  get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
    "Estás usando la versión de Songbird #{params[:agent][0]}"
  end

  get '/foo' do
    # Coincide con browsers que no sean songbird
  end

Otras condiciones disponibles son +host_name+ y +provides+:

  get '/', :host_name => /^admin\./ do
    "Área de Administración, Acceso denegado!"
  end

  get '/', :provides => 'html' do
    haml :index
  end

  get '/', :provides => ['rss', 'atom', 'xml'] do
    builder :feed
  end

Podés definir tus propias condiciones fácilmente:

  set(:probabilidad) { |valor| condition { rand <= valor } }

  get '/gana_un_auto', :probabilidad => 0.1 do
    "Ganaste!"
  end

  get '/gana_un_auto' do
    "Lo siento, perdiste."
  end

=== Valores de Retorno

El valor de retorno de un bloque de ruta determina al menos el cuerpo de la
respuesta que se le pasa al cliente HTTP o al siguiente middleware en la pila
de Rack. Lo más común es que sea un string, como en los ejemplos anteriores.
Sin embargo, otros valor también son aceptados.

Podés devolver cualquier objeto que sea una respuesta Rack válida, un objeto
que represente el cuerpo de una respuesta Rack o un código de estado HTTP:

* Un arreglo con tres elementos: <tt>[estado (Fixnum), cabeceras (Hash), cuerpo de la respuesta (responde a #each)]</tt>
* Un arreglo con dos elementos: <tt>[estado (Fixnum), cuerpo de la respuesta (responde a #each)]</tt>
* Un objeto que responde a <tt>#each</tt> y que le pasa únicamente strings al bloque dado
* Un Fixnum representando el código de estado

De esa manera podemos, por ejemplo, implementar fácilmente un streaming:

    class Stream
      def each
        100.times { |i| yield "#{i}\n" }<commit_msg>doc condition with multiple args in Spanish readme<commit_after>= Sinatra
<i>Atención: Este documento es una traducción de la versión en inglés y puede estar desactualizado.</i>

Sinatra es un DSL para crear aplicaciones web rápidamente en Ruby con un mínimo
esfuerzo:

  # miapp.rb
  require 'sinatra'

  get '/' do
    'Hola mundo!'
  end

Instalá la gem y ejecutá la aplicación con:

  gem install sinatra
  ruby -rubygems miapp.rb

Podés verla en: http://localhost:4567

Es recomendable además ejecutar <tt>gem install thin</tt>, ya que Sinatra lo va
a utilizar cuando esté disponible.

== Rutas

En Sinatra, una ruta está compuesta por un método HTTP y un patrón de una URL.
Cada ruta se asocia con un bloque:

  get '/' do
    .. mostrar algo ..
  end

  post '/' do
    .. crear algo ..
  end

  put '/' do
    .. reemplazar algo ..
  end

  patch '/' do
    .. modificar algo ..
  end

  delete '/' do
    .. aniquilar algo ..
  end

  options '/' do
    .. informar algo ..
  end


Las rutas son comparadas en el orden en el que son definidas. La primer ruta
que coincide con la petición es invocada.

Los patrones de las rutas pueden incluir parámetros nombrados, accesibles a
través de el hash <tt>params</tt>:

  get '/hola/:nombre' do
    # coincide con "GET /hola/foo" y "GET /hola/bar"
    # params[:nombre] es 'foo' o 'bar'
    "Hola #{params[:nombre]}!"
  end

También podés acceder a los parámetros nombrados usando parámetros de bloque:

  get '/hola/:nombre' do |n|
    "Hola #{n}!"
  end

Los patrones de ruta también pueden incluir parámetros splat (o wildcard),
accesibles a través del arreglo <tt>params[:splat]</tt>:

  get '/decir/*/al/*' do
    # coincide con /decir/hola/al/mundo
    params[:splat] # => ["hola", "mundo"]
  end

  get '/descargar/*.*' do
    # coincide con /descargar/path/al/archivo.xml
    params[:splat] # => ["path/al/archivo", "xml"]
  end

O, con parámetros de bloque:

  get '/descargar/*.*' do |path, ext|
    [path, ext] # => ["path/al/archivo", "xml"]
  end

Rutas con Expresiones Regulares:

  get %r{/hola/([\w]+)} do
    "Hola, #{params[:captures].first}!"
  end

O con un parámetro de bloque:

  get %r{/hola/([\w]+)} do |c|
    "Hola, #{c}!"
  end

Los patrones de ruta pueden contener parámetros opcionales:

  get '/posts.?:formato?' do
    # coincide con "GET /posts" y además admite cualquier extensión, por
    # ejemplo, "GET /posts.json", "GET /posts.xml", etc.
  end

=== Condiciones

Las rutas pueden incluir una variedad de condiciones de selección, como por
ejemplo el user agent:

  get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
    "Estás usando la versión de Songbird #{params[:agent][0]}"
  end

  get '/foo' do
    # Coincide con browsers que no sean songbird
  end

Otras condiciones disponibles son +host_name+ y +provides+:

  get '/', :host_name => /^admin\./ do
    "Área de Administración, Acceso denegado!"
  end

  get '/', :provides => 'html' do
    haml :index
  end

  get '/', :provides => ['rss', 'atom', 'xml'] do
    builder :feed
  end

Podés definir tus propias condiciones fácilmente:

  set(:probabilidad) { |valor| condition { rand <= valor } }

  get '/gana_un_auto', :probabilidad => 0.1 do
    "Ganaste!"
  end

  get '/gana_un_auto' do
    "Lo siento, perdiste."
  end

Si tu condición acepta más de un argumento, podés pasarle un arreglo.  Al
definir la condición puede resultarte conveniente utilizar el operador splat en
la lista de parámetros:

  set(:autorizar) do |*roles|   # <- mirá el splat
    condition do
      unless sesion_iniciada? && roles.any? {|rol| usuario_actual.tiene_rol? rol }
        redirect "/iniciar_sesion/", 303
      end
    end
  end

  get "/mi/cuenta/", :autorizar => [:usuario, :administrador] do
    "Detalles de mi cuenta"
  end

  get "/solo/administradores/", :autorizar => :administrador do
    "Únicamente para aministradores!"
  end

=== Valores de Retorno

El valor de retorno de un bloque de ruta determina al menos el cuerpo de la
respuesta que se le pasa al cliente HTTP o al siguiente middleware en la pila
de Rack. Lo más común es que sea un string, como en los ejemplos anteriores.
Sin embargo, otros valor también son aceptados.

Podés devolver cualquier objeto que sea una respuesta Rack válida, un objeto
que represente el cuerpo de una respuesta Rack o un código de estado HTTP:

* Un arreglo con tres elementos: <tt>[estado (Fixnum), cabeceras (Hash), cuerpo de la respuesta (responde a #each)]</tt>
* Un arreglo con dos elementos: <tt>[estado (Fixnum), cuerpo de la respuesta (responde a #each)]</tt>
* Un objeto que responde a <tt>#each</tt> y que le pasa únicamente strings al bloque dado
* Un Fixnum representando el código de estado

De esa manera podemos, por ejemplo, implementar fácilmente un streaming:

    class Stream
      def each
        100.times { |i| yield "#{i}\n" }
{'fraction_non_alphanumeric': 0.11372679045092839, 'fraction_numerical': 0.002541998231653404, 'mean_word_length': 3.183541377716135, 'pattern_counts': {'":': 0, '<': 34, '<?xml version=': 0, '>': 49, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 10}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3164579', 'n_tokens_mistral': 3334, 'n_tokens_neox': 3273, 'n_words': 1191}