1 Star 0 Fork 0

frech / rubyframework

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

该项目为《Rebuilding Rails》一书中的示例并完成该书的章后练习。

目的:旨在了解元编程以及 Rails 的架构。

元编程示例:

  1. Rails 要求文件命名为下划线,类命名为驼峰,这样才会自动加载相应文件的原因:使用了 const_missingconst_get 方法。当调用了一个类名时,因为类名在ruby中是属于常量(大写),而又没有引进该文件的时候就会调用 const_missing 方法。

    class Object
      def self.const_missing(c)
        return nil if @calling_const_missing
    
        @calling_const_missing = true
        require Rubyframework.to_underscore(c.to_s)
        klass = Object.const_get(c)
        @calling_const_missing = false
    
        klass
      end
    end
    

    此外,在通过路由地址获取controller和action的时候也使用到了const_get方法。

    def get_controller_and_action(env)
      _, cont, action, after =
        env['PATH_INFO'].split('/', 4)
      cont = cont.capitalize
      cont += 'Controller'
    
      [Object.const_get(cont), action]
    end
  2. 因为几乎所有的web框架都使用了rack作为App服务器,此书例子也不例外。所以需要定义一个Proc或者命名为call的方法。在输入地址后,rack就会调用call方法去处理逻辑。我们通过上面方法获取了controller和action后,怎么根据不同的controller和action去处理不同的逻辑呢?send方法搞定!书中给出的例子如下:

    klass, act = get_controller_and_action(env)
    controller = klass.new(env)
    text = controller.send(act)
  3. ORM中在查询数据库时常常会使用 find_by_xxx() 的方法。在此书使用文件的json格式作为储存数据一节中,最后提到的练习题让你实现一个类似 ActiveRecord 的 find_all_by_xxx() 方法。我使用了 method_missing 并用正则匹配方法名,匹配了就遍历文件寻找。没有匹配就调用 super 方法使其抛异常。

    def self.method_missing(method_sym, *arguments, &block)
      if method_sym.to_s =~ /^find_all_by_(.*)/
        array = []
        FileModel.all.each do |hash|
          if !hash[$1].nil? && hash[$1] == arguments[0]
            array << hash
          end
        end
        array
      else
        super
      end
    end
  4. 在渲染模版的时候,为了使在controller定义的实例变量能在模版里使用。我通过 instance_variablesinstance_variable_get 方法获取所有实例变量并传到模版中。

    def get_instance_variables
      hash = {}
      self.instance_variables.each do |attribute|
        hash[attribute] = self.instance_variable_get(attribute)
      end
      hash
    end
  5. 第七章练习题中,原来的hash是使用形式如hash['key']来获取值的,但是Rails中是通过调用方法,即hash.key来获取值。此时可以使用 define_method 或者 method_missing 来实现。

    # define_method 实现方式
    @hash.each do |key, value|
      define_method("#{key}") do
        value
      end
    end
    
    #method_missing 实现方式
    def method_missing(name, *args, &block)
      return @hash[name.to_s] if @hash[name.to_s]
      super
    end
  6. 最后一章适配路由中有个用到 instance_eval 方法的例子。我们知道这个方法会在一个对象的上下文执行一个块,把这个块称为 Context Probe。就像是一个深入到对象中的代码片段。

    • 在测试到web应用中,就像使用rails到路由一样写了如下路由。

      app = BestQuotes::Application.new
      use Rack::ContentType
      
      app.route do
        match "", "quotes#index"
        match "sub-app", proc { [200, {}, ["Hello, sub-app!"]] }
        # default routes
        match ":controller/:id/:action"
        match ":controller/:id", default: { "action" => "show" }
        match ":controller", default: { "action" => "index" }
      end
    • 而在routing.rb里,使用了 instance_eval 去调用match方法,此处就相当于 @route_obj.match("", "quotes#index"),并依次调用

      def route(&block)
        @route_obj ||= RouteObject.new
        @route_obj.instance_eval(&block)
      end
The MIT License (MIT) Copyright (c) 2017 frech Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

《Rebuilding Rails》一书中的示例以及该书的章后练习。 展开 收起
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
1
https://gitee.com/frech/rubyframework.git
git@gitee.com:frech/rubyframework.git
frech
rubyframework
rubyframework
master

搜索帮助