Ruby Sinatra 学习笔记,及简单模仿 Sinatra

error250 · 2016年08月14日 · 2540 次阅读

Sinatra 学习笔记 笔记 1. 向 main 添加方法 test.rb:

module Hh
  module Test
    def self.hh
      define_method("ms") do |*args, &block|
        return super(*args, &block) if respond_to? "ms"#如果定义了该方法,那么执行新定义的方法。
        p args
      end
    end
    hh
  end
end
extend Hh::Test

向 main 添加了 ms 方法 app.rb:

require './test'
p methods

笔记 2.向 module 添加模块变量的读写方法

module Test
  class << self
    Attr_accessor :name
  end
end

以后可以像下面这样用了:

Test.name = 12
P Test.name

笔记 3. 利用参数默认值,声明一个变量

def set(option, value = (not_set = true) );end

此时若未给出 value 的值,not_set 会是 true.否则为 nil

笔记 4.ruby 内置常量 ARGV ARGV 是一个保存命令行参数的 Array

笔记 5.at_exit 函数 Kernel 函数 at_exit:程序结束的时候调用 参数:block 举例:

at_exit{ p done }

笔记 6.操作符 === 判断变量数据的类型

a = 'hh'
String === a # => true
a = 12
String === a # => false

笔记 7.sinatra 的启动 sinatra 源代码:

module Sinatra
  class Application < Base
    ...
  end

  at_exit { Application.run! if $!.nil? && Application.run? }
end

利用 at_exit 函数,自动启动 Rack.

简单模仿 sinatra

代码清单 1:min_sinatra.rb

=begin
  Web Frame Work
=end
require 'rack'

module Min_Sinatra
  #
  # set Module instance
  #   * settings - settings for web server
  #     -> route - all route sets from user
  #
  class << self
    attr_accessor :settings
  end
  self.settings = {:route => {:get =>[],:post=>[],:put=>[],:delete=>[]}}
  #
  # Rack App
  #
  class App
    class << self
      attr_accessor :params
      attr_accessor :env
    end
    self.env = {}
    #
    # function not_found
    #
    def not_found
      [200,{},["<h1>404 Not Found</h1>"]]
    end
    #
    # Rack app call function interface
    #
    def call env
      rel = nil
      self.class.env = env
      #
      # match route
      # support : String, Regexp
      # rel - nil| body| [status,{header},[bodys]]
      #
      req = Rack::Request.new env
      self.class.params = req.params
      method = env["REQUEST_METHOD"].downcase
      Min_Sinatra.settings[:route][method.to_sym].each do |p|
        case p[:path]
        when String
          if env["REQUEST_PATH"] == p[:path]
            rel = p[:proc].call
          end
        when Regexp
          if env["REQUEST_PATH"] =~ p[:path]
            rel = p[:proc].call
          end
        else
          throw :illegal_route
        end
      end
      #
      # anaylize rel
      # nil   - return not_found
      # Array - return rel if match [fixnum, hash, array]
      # other - return [200, {}, [other.to_s]]
      #
      if rel.nil?
        not_found
      else
        case rel
        when Array
          if Fixnum === rel[0] and Hash === rel[1] and Array === rel[2]
            rel
          else
            [200,{},[rel.to_s]]
          end
        else
          [200,{},[rel.to_s]]
        end
      end
    end
    #
    # Session
    #
    def self.session
      env["rack.session"]
    end
    #
    # start server
    #
    def self.start
      statics = Rack::File.new 'static'
      begin
        wfwapp = Rack::Builder.new do
          use Rack::Session::Cookie, :secret => Time.new.to_s,:expire_after => 12
          run Rack::Cascade.new [statics, Min_Sinatra::App.new]
        end
        Rack::Handler::WEBrick.run wfwapp
      rescue Exception => e
      ensure
        Rack::Handler::WEBrick.shutdown
      end
    end
    #
    # redirect to uri
    #
    def self.redirect uri
      targetURI = nil
      if uri =~ /http:\/\//
        targetURI = uri
      else
        targetURI = "http://127.0.0.1:" + env["SERVER_PORT"] + uri
      end
      [302,{"Location"=> targetURI},[]]
    end

  end
  #
  # function register
  #
  def self.register *methods
    methods.each do | method_name |
      define_method(method_name) do | *path, &block |
        return (Min_Sinatra::App.send method_name, *path, &block) if Min_Sinatra::App.respond_to? method_name
        throw :syntax_error if path[0].nil? or block.nil?
        throw :illegal_route if !(String===path[0]) and !(Regexp === path[0])
        Min_Sinatra.settings[:route][method_name] << {:path => path[0], :proc => block}
      end
    end
  end
  register :get, :post, :put, :delete, :start, :params, :redirect, :session

  at_exit { Min_Sinatra::App.start if $!.nil? || $!.is_a?(SystemExit) && $!.success?}
end
extend Min_Sinatra

代码清单 2:示例 test.rb

require './app'

get '/' do
  redirect '/index.html'
end

post '/app' do
  session['uname'] = params['uname']
  p session['uname']
  redirect '/start'
end

get '/start' do
  "Welcome" + session['uname']
end

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请 注册新账号