Ruby:在使用模块扩展实例时执行一些操作

Ruby:在使用模块扩展实例时执行一些操作,ruby,Ruby,我想在使用扩展实例时执行一些代码。当实例化一个类而不是一个模块时,有点像初始化 以下是扩展的: 您可以在模块中定义: module Mod def self.extended(base) raise "Cannot extend #{base}" unless base.is_a?(GoodKlass) end def hello "Hello from Mod.\n" end end 您可以在模块中定义: module Mod def self.exte

我想在使用扩展实例时执行一些代码。当实例化一个类而不是一个模块时,有点像初始化

以下是扩展的:

您可以在模块中定义:

module Mod
  def self.extended(base)
    raise "Cannot extend #{base}" unless base.is_a?(GoodKlass)
  end

  def hello
    "Hello from Mod.\n"
  end
end
您可以在模块中定义:

module Mod
  def self.extended(base)
    raise "Cannot extend #{base}" unless base.is_a?(GoodKlass)
  end

  def hello
    "Hello from Mod.\n"
  end
end

你对这个问题的评论,回应了我的评论,证实了我的怀疑。您所做的不是扩展该类,而是扩展该类的特定实例。让我们看看你的代码是做什么的

good = GoodKlass.new
good.hello       #=> "Hello from GoodKlass.\n"
GoodKlass.hello  #=> NoMethodError: undefined method `hello' for GoodKlass:Class
good.extend(Mod)
GoodKlass.hello  #=> NoMethodError: undefined method `hello' for GoodKlass:Class
good.hello       #=> "Hello from Mod.\n"
very_good = GoodKlass.new
very_good.hello  #=> "Hello from GoodKlass.\n"
如您所见,
hello
仅在实例
good
上定义

如果这不是你想要的,有两种可能性。我参考

class VeryGoodKlass
end
在讨论两者时

一,<代码>扩展类

在您的应用程序中(参考对问题的注释),这种方法允许您创建一个类方法
File::jpg?
,该类方法将被调用
File.jpeg?(“cat.jpg”)

要将
Mod
的实例方法
hello
转换为
GoodKlass
的类方法,需要使用扩展该类(而不是该类的实例)。要防止其他类扩展模块,请在模块中使用回调方法

module Mod
  def self.extended(base)
    raise ArgumentError, "Cannot extend #{base}" unless base == GoodKlass
  end
  def hello
    "Hello from Mod"
  end
end

class GoodKlass
  def self.hello
    "Hello from GoodKlass"
  end
end

GoodKlass.hello           #=> "Hello from GoodKlass"
GoodKlass.extend(Mod)
GoodKlass.hello           #=> "Hello from Mod"
VeryGoodKlass.extend(Mod) #=> ArgumentError: Cannot extend VeryGoodKlass
二,。将模块包括在类中

要将
Mod
的实例方法添加到
GoodKlass
(保留它们的实例方法),您需要使用包含模块。要防止其他类包含模块,请在模块中使用回调方法

module Mod
  def self.extended(base)
    raise ArgumentError, "Cannot extend #{base}" unless base == GoodKlass
  end
  def hello
    "Hello from Mod"
  end
end

class GoodKlass
  def self.hello
    "Hello from GoodKlass"
  end
end

GoodKlass.hello           #=> "Hello from GoodKlass"
GoodKlass.extend(Mod)
GoodKlass.hello           #=> "Hello from Mod"
VeryGoodKlass.extend(Mod) #=> ArgumentError: Cannot extend VeryGoodKlass
在应用程序中,这将允许您编写一个实例方法
File 35; jpg?
1,如下所示:

f = File.new('cat.jpg')
f.jpg?
你可以这样做

module Mod
  def self.included(base)
    raise ArgumentError, "Cannot include #{base}" unless base == GoodKlass
  end
  def hello
    "Hello"
  end
end

class GoodKlass
end

good = GoodKlass.new
GoodKlass.include(Mod)
GoodKlass.hello            #=> NoMethodError: undefined method `hello' for GoodKlass:Class
good.hello                 #=> "Hello" 
VeryGoodKlass.include(Mod) #=> ArgumentError: Cannot include VeryGoodKlass

一,。也许
File.basename(f.path).以“.jpg”结尾?

你对这个问题的评论,回应了我的评论,证实了我的怀疑。您所做的不是扩展该类,而是扩展该类的特定实例。让我们看看你的代码是做什么的

good = GoodKlass.new
good.hello       #=> "Hello from GoodKlass.\n"
GoodKlass.hello  #=> NoMethodError: undefined method `hello' for GoodKlass:Class
good.extend(Mod)
GoodKlass.hello  #=> NoMethodError: undefined method `hello' for GoodKlass:Class
good.hello       #=> "Hello from Mod.\n"
very_good = GoodKlass.new
very_good.hello  #=> "Hello from GoodKlass.\n"
如您所见,
hello
仅在实例
good
上定义

如果这不是你想要的,有两种可能性。我参考

class VeryGoodKlass
end
在讨论两者时

一,<代码>扩展类

在您的应用程序中(参考对问题的注释),这种方法允许您创建一个类方法
File::jpg?
,该类方法将被调用
File.jpeg?(“cat.jpg”)

要将
Mod
的实例方法
hello
转换为
GoodKlass
的类方法,需要使用扩展该类(而不是该类的实例)。要防止其他类扩展模块,请在模块中使用回调方法

module Mod
  def self.extended(base)
    raise ArgumentError, "Cannot extend #{base}" unless base == GoodKlass
  end
  def hello
    "Hello from Mod"
  end
end

class GoodKlass
  def self.hello
    "Hello from GoodKlass"
  end
end

GoodKlass.hello           #=> "Hello from GoodKlass"
GoodKlass.extend(Mod)
GoodKlass.hello           #=> "Hello from Mod"
VeryGoodKlass.extend(Mod) #=> ArgumentError: Cannot extend VeryGoodKlass
二,。将模块包括在类中

要将
Mod
的实例方法添加到
GoodKlass
(保留它们的实例方法),您需要使用包含模块。要防止其他类包含模块,请在模块中使用回调方法

module Mod
  def self.extended(base)
    raise ArgumentError, "Cannot extend #{base}" unless base == GoodKlass
  end
  def hello
    "Hello from Mod"
  end
end

class GoodKlass
  def self.hello
    "Hello from GoodKlass"
  end
end

GoodKlass.hello           #=> "Hello from GoodKlass"
GoodKlass.extend(Mod)
GoodKlass.hello           #=> "Hello from Mod"
VeryGoodKlass.extend(Mod) #=> ArgumentError: Cannot extend VeryGoodKlass
在应用程序中,这将允许您编写一个实例方法
File 35; jpg?
1,如下所示:

f = File.new('cat.jpg')
f.jpg?
你可以这样做

module Mod
  def self.included(base)
    raise ArgumentError, "Cannot include #{base}" unless base == GoodKlass
  end
  def hello
    "Hello"
  end
end

class GoodKlass
end

good = GoodKlass.new
GoodKlass.include(Mod)
GoodKlass.hello            #=> NoMethodError: undefined method `hello' for GoodKlass:Class
good.hello                 #=> "Hello" 
VeryGoodKlass.include(Mod) #=> ArgumentError: Cannot include VeryGoodKlass

一,。可能
File.basename(f.path).end_以?(“.jpg”)

扩展实例而不是类是不常见的。我很好奇你为什么要这么做。顺便说一句,你有一个打字错误:
expand
应该是
extend
@CarySwoveland,谢谢。例如,我想扩展
文件
类,以确定它是什么格式,例如
是jpeg?
,并提供一些方法来提取元数据,如
#date_take
。扩展实例而不是类是不寻常的。我很好奇你为什么要这么做。顺便说一句,你有一个打字错误:
expand
应该是
extend
@CarySwoveland,谢谢。例如,我想扩展
文件
类,以确定它是什么格式,例如
是jpeg?
,并提供一些方法来提取元数据,如
#date_take
。谢谢,您了解了我关于扩展实例的想法。由于我试图做的事情太长,无法发表评论,因此我发布了一个后续问题:谢谢,您了解我关于扩展实例的想法。由于我试图做的事情太长,无法发表评论,我发布了一个后续问题: