ruby - 仅特定于实例的方法?它们在 Ruby 中叫什么?

标签 ruby singleton

我知道有“实例方法”、“类方法”,但是这些类型的方法叫什么,例如:

s1 = "This is my STRING!"

def s1.m1
  downcase
end

p s1     # => "This is my STRING!"
p s1.m1   # => "this is my string!"

在“string”类的s1“实例”上调用的“m1”方法是什么类型的方法?这真的很奇怪,因为我根本不知道如果我尝试这是可能的:

s2 = "This is ANOTHER string"
s2.m1 # => Won't work!

哪一种说得通,但不确定为什么在类的实例上定义像 m1 这样的方法完全有用。

最佳答案

它们被称为单例方法,可以定义如下:

class Person
  def favorite_meal
    "Big Mac"
  end
end

Fred, Joe = 2.times.map { Person.new }

def Fred.favorite_meal
  "Le Big Mac"
end

Joe.favorite_meal #=> Big Mac
Fred.favorite_meal #=> Le Big Mac

定义相同单例方法的其他方法是:

Fred.define_singleton_method :favorite_meal do "Le Big Mac" end

和:

class << Fred
  def favorite_meal
    "Le Big Mac"
  end
end

愿原力与你同在。


更新:回答评论中的 2 个问题。

让我从第二个开始。无论您使用常量还是变量,都取决于您。写 fred = Person.new 完全没问题.但是:

  1. 具有不同属性的对象通常需要适当的名称,适本地大写。

  2. 我写了一个有用的 gem,y_support/name_magic ,它通过分配给常量来工作。

通过 gem install y_support 安装它,然后尝试:

require 'y_support/name_magic'

class Dog
  include NameMagic
  def speak; puts "Bow wow!" end
end

Spot, Rover = 2.times.map { Dog.new }

现在 Dog类知道它的实例,实例知道它们的名字。

Dog.instances.map { |dog| dog.name } #=> :Spot, :Rover
Dog.instances.names # the simpler way to say the same

这在这个特定示例中没有用(在其他地方非常有用),但无论如何,它让我养成了给具有个性的对象大写专有名称的习惯。

关于第一个问题,def Fred.foobar是最基本的一次性单例方法定义。如果你想定义几个单例方法,或者别名,或者在单例类中包含一个模块,使用class << Fred :

module Foo
  def bar; "Fretbar!" end
end

class << Fred
  include Foo
  alias le_favorite favorite_meal
end

Fred.bar #=> Fretbar!
Fred.le_favorite #=> "Le Big Mac"

Fred.define_singleton_method 让最先进的东西成为可能语法,以及我之前没有提到的第 4 种方式:

local_var = 42

Fred.singleton_class.class_exec do
  define_method :baz do local_var + 1 end
end

Fred.baz #=> 43

这种方式使用闭包,它保留对变量 local_var 的绑定(bind).试试看

local_var = 32
Fred.baz #=> 33

所以这就是闭包语法的特别之处,它通常是神奇地解决讨厌的编程问题的天赐之物。

关于ruby - 仅特定于实例的方法?它们在 Ruby 中叫什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19754791/

相关文章:

javascript - Alertify 警报确认对话框不适用于 Ruby on Rails

java - 如何在 Java Singleton 枚举构造函数中调用方法?

java - 为什么在Java中设计单例模式时需要双重检查锁?

java - 单例设计模式双重检查锁定

javascript - 使用 jQuery 从外部 JSON 站点获取数据,Singleton 类

c++ - 为了在测试中调用析构函数(用于测试),将基类静态转换为派生类有多可怕?

ruby-on-rails - Rails - 从 acts_as_follower gem 订购循环

ruby - 由两个不同的分隔符分割的字符串

ruby-on-rails - 使用 rails 设置 backbone.js 时为 "SyntaxError: unexpected }"

ruby-on-rails - Rails - 内联 CSS