`

Ruby中的类方法与实例方法

阅读更多
原文:http://railstips.org/2009/5/11/class-and-instance-methods-in-ruby
-----------------------------------------------------
类方法在从一个类直接调用的,而实例方法是从一个类的实例来调用 的。这儿给一个简短的例子来说说具体一些情况。
class Foo
  def self.bar
    puts 'class method'
  end

  def baz
    puts 'instance method'
  end
end

Foo.bar # => "class method" 
Foo.baz # => NoMethodError: undefined method ‘baz’ for Foo:Class

Foo.new.baz # => instance method
Foo.new.bar # => NoMethodError: undefined method ‘bar’ for #<Foo:0x1e820>


看来有什么不同了吗?bar是一个类的方法,因此可以直接在Foo类上正常调用。baz是一人实例方法,因此在Foo类上调用就引发了一个NoMethodError。在接下来的几代码中,我们都从Foo的一个实例(Foo.new)上调用。

现在我们有了一些基础,让我来展示一下创建类方法和实例方法的几种方式和它们的用途。

类方法(Class Methods)

Ruby语言扩展性很强,因此定义一个类方法可以有多种方式。
以下是最为常见的几种方式:
# Way 1
class Foo
  def self.bar
    puts 'class method'
  end
end

Foo.bar # "class method" 

# Way 2
class Foo
  class << self
    def bar
      puts 'class method'
    end
  end
end

Foo.bar # "class method" 

# Way 3
class Foo; end
def Foo.bar
  puts 'class method'
end

Foo.bar # "class method"


我最喜欢使用第一种方法。当我一看到self.method_name我就立即意识到那是一个类方法。许多人都用第二种方法,它在Rails中用得相当地多。

使用方式二 没有什么过错,但是当你在一个类中有一大堆的类方法在<< 块中,很难认出哪些是类方法,哪些是实例方法,因为它们都是def method_name形式。如果没有注意到这一点,你用使用这种方法,就会明白我所说的这一点。

方式三目前不很常见,它经常被快速地给一个类添加类方法。这里并不是只有这三种方式来创建类方法(Class Methods),但是它们是我见过最多的。
So when would you use a class method? Class methods are for anything that does not deal with an individual instance of a class. ActiveRecord::Base#find is one example. If you look in ActiveRecord::Base, you’ll see something like this:
module ActiveRecord
  class Base
    # some stuff
    class << self
      def find(...)
        # blah
      end
    end
  end
end


Looks familiar, eh? Some other uses of class methods in Rails are validations and associations in ActiveRecord and before/after/around filters in ActionPack. The way this works is something like this (simplified for clarity):
module ActiveRecord
  class Base
    def self.validates_presence_of(...)
      # make sure present
    end
  end
end

class Foo < ActiveRecord::Base
  validates_presence_of :bar
end


当你写上validates_presence_of,AR:Base中的这个方法就会被调用。

实例方法(Instance Methods)
Enough about class methods, lets move on. Instance methods are a bit more simple. Here are a few common ways that instance methods are defined.
# Way 1
class Foo
  def baz
    puts 'instance method'
  end
end

Foo.new.baz # "instance method" 

# Way 2
class Foo
  attr_accessor :baz
end

foo = Foo.new
foo.baz = 'instance method'
puts foo.baz

# Way 3
class Foo; end

foo = Foo.new
def foo.bar
  puts 'instance method'
end

Foo.new.baz # "instance method"


关键的不同点是:实例方法只能来实例来调用,因此你必须来创建一个类的实例来调用它们(Foo.new)。另外,比起这个,有更多的方法来设义实例方法,如果你掌握元编程(meta programming)。

So what are some examples uses of instance methods in Rails, to give you a better idea? Ever do a find in a destroy action and then call destroy on the found instance? destroy is an instance method.
class FoosController < ActionController
  def destroy
    foo = Foo.find(params[:id])
    foo.destroy
    redirect_to foos_url
  end
end

So are save and update_attributes, which you have definitely used before if you’ve done any Rails.
foo = Foo.new(:title => 'Bar')
foo.save # is an instance method


推论
类方法(Class methods)只能被类来调用,而实例方法(instance methods)只能被类的实例来调用。理解这个很容易,但我刻我学Ruby的时候被这个搞迷糊了。希望写的这个有些帮助。如果你们有什么不懂的,问我好了。

接下来的一篇是关于Ruby中的Include和Extend,敬请期待。
分享到:
评论

相关推荐

    Ruby 方法、类

    在Ruby中,方法和类是构建程序的基本元素,它们是实现代码重用和组织的关键概念。 ### 方法(Methods) 方法在Ruby中是可重复使用的代码块,它们接受参数,执行特定任务,并可能返回值。方法定义使用`def`关键字...

    Ruby入门教程中文PDF 附实例

    类和对象是Ruby的核心概念,你可以自定义类并创建实例。例如,创建一个名为`Person`的类并初始化姓名: ```ruby class Person def initialize(name) @name = name end end person = Person.new("Alice") ``` Ruby...

    ruby初级中文教程与实例

    五、实例与实践 在Ruby语言中文教程中,你将通过大量实例学习这些概念,例如: 1. 字符串操作:了解字符串拼接、格式化输出、查找替换等方法。 2. 数组操作:学习数组的增删改查、排序、遍历等技巧。 3. 哈希操作...

    类变量、全局变量、实例变量, 多态、为什么ruby、ruby编码规范

    本文将深入探讨Ruby语言中的类变量、全局变量、实例变量,以及多态的概念,并结合Ruby编码规范来阐述如何有效地编写代码。 一、类变量 类变量在Ruby中以`@@`前缀表示,它们是属于类或模块的共享变量,不会被类的...

    Ruby中文教程,佩戴实例

    变量在Ruby中有四种类型:局部变量、实例变量、类变量和全局变量,它们都有特定的标识符前缀。数据类型包括基本类型和复杂类型,如数组、哈希(字典)、集合等。 函数和方法是Ruby的核心组成部分。你可以定义自己的...

    Ruby中类变量和实例变量的比较

    ### Ruby中类变量和实例变量的比较 在Ruby编程语言中,类变量和实例变量都是用来存储数据的重要机制。它们虽然都是变量,但在用途、作用范围、生命周期等方面有着明显的区别。接下来,我们将详细介绍这两者之间的四...

    Ruby类实例变量、类实例方法和类变量、类方法的区别

    在Ruby语言中,类实例变量、类实例方法与类变量和类方法是构成面向对象编程模型的重要组成部分。它们各自有不同的用途和行为特性,下面详细介绍这些概念的区别以及它们的使用场景。 首先,类实例变量和类实例方法都...

    ruby实用函数和实例

    尽管没有具体说明文件内容,但通常在Ruby中处理文本文件,我们会用到File类,它提供了打开、读取、写入和关闭文件的方法。例如,`File.open('filename.txt', 'r')`可以用来读取文件,`File.write('filename.txt', '...

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

    通过使用钩子方法,可以让我们在Ruby的类或模块的生命周期中进行干预,可以极大的提高编程的灵活性。 与生命周期相关的钩子方法有下面这些: 类与模块相关 Class#inherited Module#include Module#prepended ...

    Ruby Ruby入门级实例

    Ruby入门级实例

    实例讲解Ruby使用设计模式中的装饰器模式的方法

    Ruby中的装饰器模式是一种设计模式,它允许我们动态地向对象添加新的行为或职责,而无需修改原有类的代码。这种模式比继承更加灵活,因为它可以在运行时改变对象的行为,而不是在编译时通过类继承来实现。装饰器模式...

    Ruby-Functo是ruby中的可组合方法对象

    在传统的面向对象编程中,我们通常会定义类和实例方法来封装逻辑,而在函数式编程中,我们倾向于将函数作为一等公民,这意味着它们可以被赋值给变量、作为参数传递,也可以作为其他函数的返回值。 在Ruby中,Functo...

    Ruby 语言中类与对象简介,入门级语法介绍

    ### Ruby 语言中类与对象简介及入门级语法详解 #### 一、Ruby中的面向对象概念 Ruby是一种纯粹的面向对象编程语言,这意味着在Ruby中几乎所有的内容都是对象。面向对象编程(Object-Oriented Programming,OOP)的...

    ruby收取邮件实例

    ### Ruby收取邮件实例详解 在IT领域,使用编程语言处理电子邮件是常见的需求之一,而Ruby作为一门优雅且功能丰富的脚本语言,在这方面提供了强大的支持。本文将深入解析一个Ruby脚本,该脚本用于通过POP3协议收取...

    ruby 中文文档 必备资料

    在Ruby中,异常类是继承自`StandardError`的,你可以自定义异常类来处理特定类型的错误。 Ruby on Rails是Ruby最著名的Web开发框架,它遵循MVC(模型-视图-控制器)架构模式。这份文档可能也涵盖了Rails的相关内容...

    ruby中文文档中心资料

    在Ruby中,类是对象的蓝图,而对象是类的实例。类定义了对象的属性(或称为实例变量)和行为(或称为方法)。Ruby支持单继承,但通过模块,可以实现一种形式的多继承,即混入。模块可以包含方法和常量,可以通过`...

    Ruby面向对象编程中类的方法与类的扩展

    ### Ruby面向对象编程中类的方法与类的扩展 在Ruby这门动态的、面向对象的脚本语言中,类和方法扮演着极其重要的角色。本文将深入探讨Ruby中类的方法以及类的扩展,并通过示例代码帮助理解这些概念。 #### 类方法 ...

    ruby中文教程,从基础到深入的让你学习ruby

    变量在Ruby中有四种类型:局部变量(以小写字母或下划线开头)、实例变量(以`@`开头)、类变量(以`@@`开头)和全局变量(以`$`开头)。数据类型包括字符串、数字、布尔值、数组、哈希等。控制结构包括条件语句(如...

    ruby中文教程(源代码)

    - 函数与方法:Ruby中的函数被称为方法,可以定义在类或模块中,支持块(block)和 Proc 对象。 2. **面向对象编程(OOP)** - 类与对象:Ruby是纯面向对象的语言,一切皆对象。你可以创建自定义类来封装数据和...

Global site tag (gtag.js) - Google Analytics