• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • vbs
  • DOS/BAT
  • hta/htc
  • python
  • perl
  • VBA
  • ColdFusion
  • ruby
  • PowerShell
  • Lua
  • Golang
  • linux shell
您的位置:首页 > 脚本语言 >ruby > Ruby中的钩子方法详解

Ruby中的钩子方法详解

作者:junjie 字体:[增加 减小] 来源:互联网

junjie 通过本文主要向大家介绍了窗帘穿钩子方法,钩子方法,java 钩子方法,鸟笼钩子的制作方法,ruby等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

Ruby的哲学理念是基于一个基本的要素,那就是让程序员快乐。Ruby非常注重程序员的快乐,并且也提供了许多不同的方法来实现它。 它的元编程能力能够让程序员编写在运行时动态生成的代码。它的线程功能使得程序员有一种优雅的的方式编写多线程代码。 它的钩子方法能让程序员在程序运行时扩展它的行为。

上述的这些特性,以及一些其他很酷的语言方面,使得Ruby成为编写代码的优先选择之一。 本文将探讨Ruby中的一些重要的钩子方法。我们将从不同方面讨论钩子方法,如它们是什么,它们用于什么,以及我们如何使用它们来解决不同的问题。 我们同时也了解一下一些流行的Ruby框架/Gem包/库是如何使用它们来提供非常酷的特性的。

我们开始吧。

什么是钩子方法?

钩子方法提供了一种方式用于在程序运行时扩展程序的行为。 假设有这样的功能,可以在无论何时一个子类继承了一些特定的父类时收到通知, 或者是比较优雅地处理一个对象上的不可调用的方法而不是让编译器抛出异常。 这些情况就是使用钩子方法,但是它们的用法并不仅限于此。 不同的框架/库使用了不同的钩子方法来实现它们的功能。

在本文中我们将会讨论如下几个钩子方法:

1.included
2.extended
3.prepended
4.inherited
5.method_missing

included

Ruby给我们提供了一种方式使用 模块(modules) (在其他语言中被称作 混入类(mixins))来编写模块化的代码供其他的 模块/类 使用。 模块 的概念很简单,它就是一个可以在其他地方使用的独立代码块。

例如,如果我们想要编写一些代码在任何时候调用特定的方法都会返回一个静态字符串。 我们姑且将这个方法称作 name。你可能在其他地方也会想使用同一块代码。 这样最好是新建一个模块。让我们来创建一个:
module Person
  def name
    puts "My name is Person"
  end
end
</div>

这是一个非常简单的模块,仅有一个 name 方法用于返回一个静态字符串。在我们的程序中使用这个模块:

class User
  include Person
end
</div>

Ruby提供了一些不同的方法来使用模块。include 是其中之一。include 所做的就是将在 module 内定义的方法在一个 class 的实例变量上可用。 在我们的例子中,是将 Person 模块中定义的方法变为一个 User 类实例对象的方法。 这就相当于我们是将 name 方法写在 User 类里一样,但是定义在 module 里的好处是可复用。 要调用 name 方法我们需要创建一个 User 的实例对象,然后再在这个对象上调用 name 方法。例如:
User.new.name
=> My name is Person
</div>
让我们看看基于 include 的钩子方法。included 是Ruby提供的一个钩子方法,当你在一些 module 或者 class 中 include 了一个 module 时它会被调用。 更新 Person 模块:

module Person
  def self.included(base)
    puts "#{base} included #{self}"
  end

  def name
    "My name is Person"
  end
end
</div>

你可以看到一个新的方法 included 被定义为 Person 模块的类方法。当你在其他的模块或者类中执行 include Person 时,这个 included 方法会被调用。 该方法接收的一个参数是对包含该模块的类的引用。试试运行 User.new.name,你会看到如下的输出:

User included Person
My name is Person
</div>
正如你所见,base 返回的是包含该模块的类名。现在我们有了一个包含 Person 模块的类的引用,我们可以通过元编程来实现我们想要的功能。 让我们来看看 Devise是如何使用 included 钩子的。

Devise中的 included

Devise是Ruby中使用最广泛的身份验证gem包之一。它主要是由我喜欢的程序员 José Valim 开发的,现在是由一些了不起的贡献者在维护。 Devise为我们提供了从注册到登录,从忘记密码到找回密码等等完善的功能。它可以让我们在用户模型中使用简单的语法来配置各种模块:

devise :database_authenticatable, :registerable, :validatable
</div>

在我们模型中使用的 devise 方法在这里定义。 为了方便我将这段代码粘贴在下面:
def devise(*modules)
  options = modules.extract_options!.dup

  selected_modules = modules.map(&:to_sym).uniq.sort_by do |s|
    Devise::ALL.index(s) || -1  # follow Devise::ALL order
  end

  devise_modules_hook! do
    include Devise::Models::Authenticatable

    selected_modules.each do |m|
      mod = Devise::Models.const_get(m.to_s.classify)

      if mod.const_defined?("ClassMethods")
        class_mod = mod.const_get("ClassMethods")
        extend class_mod

        if class_mod.respond_to?(:available_configs)
          available_configs = class_mod.available_configs
          available_configs.each do |config|
            next unless options.key?(config)
            send(:"#{config}=", options.delete(config))
          end
        end
      end

      include mod
    end

    self.devise_modules |= selected_modules
    options.each { |key, value| send(:"#{key}=", value) }
  end
end
</div>

在我们的模型中传给 devise 方法的模块名将会作为一个数组保存在 *modules 中。 对于传入的模块调用 extract_options! 方法提取可能传入的选项。 在11行中调用 each 方法,并且每个模块在代码块中用 m 表示。 在12行中 m 将会转化为一个常量(类名),因此使用 m.to.classify 一个例如 :validatable 这样的符号会变为 Validatable 。 随便说一下 classify 是ActiveSupport的方法。

Devise::Models.const_get(m.to_classify) 会获取该模块的引用,并赋值给 mod。 在27行使用 include mod 包含该模块。 例子中的 Validatable 模块是定义在这里。 Validatable 的 included 钩子方法定义如下:
def self.included(base)
  base.extend ClassMethods
  assert_validations_api!(base)

  base.class_eval do
    validates_presence_of

您可能想查找下面的文章:

  • Ruby中钩子方法的运用实例解析
  • Ruby中的钩子方法详解

相关文章

  • ruby 正则表达式 教程
  • RUBY文档中心-学习开始
  • 浅析Ruby中的类对象的概念
  • Ruby中的Proc类及Proc的类方法Proc.new的使用解析
  • Ruby设计模式编程之适配器模式实战攻略
  • ruby实现石头剪刀布游戏示例
  • Ruby学习笔记二帮助生成Vim添加代码头的代码
  • Ruby中数组的一些相关使用方法
  • 在Ruby程序中连接数据库的详细教程
  • ruby 学习笔记(1) 初识语法

文章分类

  • vbs
  • DOS/BAT
  • hta/htc
  • python
  • perl
  • VBA
  • ColdFusion
  • ruby
  • PowerShell
  • Lua
  • Golang
  • linux shell

最近更新的内容

    • Ruby语言中的String深入理解
    • Ruby中遍历目录的简洁方法
    • 二十分钟 教你Ruby快速入门 图文教程第1/4页
    • ruby实现修改ubuntu下的hosts
    • Ruby实现发送邮件的两个方法
    • Windows下Ruby on Rails开发环境安装配置图文教程
    • Ruby中的字符串编写示例
    • Monkey Patch猴子补丁编程方式及其在Ruby中的运用
    • Ruby实现的各种排序算法
    • 初步讲解Ruby编程中的多线程

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有