gpt4 book ai didi

Ruby 中的 module_function 和 extend self异同

转载 作者:qq735679552 更新时间:2022-09-29 22:32:09 27 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章Ruby 中的 module_function 和 extend self异同由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

在阅读开源的 Ruby 代码和编写可维护性的代码经常遇到这两者的使用,那么他们两者的共同点和区别是什么呢?

module_function 。

Ruby 的 module 是 method 和 constants 的集合。module 中的method 又可分为 instance method 和 module method, 当一个 module 被 include 进一个 class ,那么 module 中的 method (注:没有被 module_function 标记的 method)就是 class 中的 instance method, instance method 需要所在的 class 被实例化之后才能被调用;被 module_function 标记的 method(不管该 method 是 public 或者 private)就是 module method 且 instance method 也会变成 private method,对于被 include 所在的 class 来说是 private method,object.module_name 会出错。module method 都能被 module_name.method_name 调用,没有被 module_function 标记的 public method 不能被 module_name.method_name 调用.

module 中的 module_function 会把 module 中的 method 变成 module method 且对于被 include 所在的 class 来说,module method 在 module 中是 private method 故 module_name.module_method 能调用,而不能被 object.module_name 调用.

module 中的 public method 对于被 include 所在的 class 来说是 instance method,故 object.public_method_in_module 能调用。如果想要非 module method 能够被 module 调用(module_name.not_module_method) ,需要引入 extend self (下文会讨论 extend self) 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# test.rb
module MyModule
  def public_meth
   p "a public method, if the module is included to a class , can be call as object.public_meth"
  end
  def module_method
   p "a module method,can be called as module_name.module_method. but can not be call as object.module_method"
  end
  private
  def private_method_to_module_function
   p "a private_method, but can be call as module_name.module_method, because it was assigned to module_function"
  end
  def private_method
   p "I am a private method"
  end
  module_function :module_method , :private_method_to_module_function
end
 
MyModule.module_method
MyModule.private_method_to_module_function
begin
  MyModule.public_meth
rescue
  p "public method can not be called by module_name.public_meth"
end
begin
  MyModule.private_method
rescue NoMethodError
  p "private method can not be called by module_name.module_method"
end
 
class MyClass
  include MyModule
end
 
obj = MyClass. new
obj.public_meth
 
begin
  obj.private_method
rescue NoMethodError
  p "private method in module can not be call by object.method_name"
end
 
begin
  obj.module_method
rescue NoMethodError
  p "module method can not be called by object.method_name, for object, module method is private instance method"
end
 
#调用
ruby test.rb
"a module method,can be called as module_name.module_method. but can not be call as object.module_method"
"a private_method, but can be call as module_name.module_method, because it was assigned to module_function"
"public method can not be called by module_name.public_meth"
"private method can not be called by module_name.module_method"
"a public method, if the module is included to a class , can be call as object.public_meth"
"private method in module can not be call by object.method_name"
"module method can not be called by object.method_name, for object, module method is private instance method"

总结就是 。

•The method will be copied to class' singleton class •The instance method's visibility will become private 。

extend self 。

Include is for adding methods to an instance of a class and extend is for adding class methods 。

extend 本质是给 class 或者 module 添加 class method 。

extend self 让 module 中的 instance method 能够被 module_name.instance_method 调用,保留 module 中原本 method 的 public 或 private 属性,但又不像 module_function 一样把被标记的 method 变成 private .

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#!/usr/bin/env ruby
# encoding: utf-8
# test_extend.rb
module MyModule
  extend self
  def public_meth
   p "a public_method extended by self can be called by module_name.public_meth and object.public_meth, included by a class"
   private_method
  end
  private
  def private_method
   p "a private method, can be call in module internal"
  end
end
 
class MyClass
  include MyModule
end
 
MyModule.public_meth
 
begin
  MyModule.private_method
rescue NoMethodError
  p "private method in extend self module can not be called module_name.private_method"
end
 
obj = MyClass. new
obj.public_meth
 
begin
  obj.private_method
rescue NoMethodError
  p "private method can not be called by object.private_method"
end
 
# 调用 ruby test_extend.rb
"a public_method extended by self can be called by module_name.public_meth and object.public_meth, included by a class"
"a private method, can be call in module internal"
"private method in extend self module can not be called module_name.private_method"
"a public_method extended by self can be called by module_name.public_meth and object.public_meth, included by a class"
"a private method, can be call in module internal"
"private method can not be called by object.private_method"

总结就是: •No method copying involved •No changes to method visibility 。

总结 。

module_function 改变 module 内 原来 method 的 public/private 属性并把改 method 变成 module method ,能够被 module_name.module_method 调用.

extend self 就是在 module 自继承,不改变 module 中 method 的 public/private 属性,能够被 module_name.public_method 。

最后此篇关于Ruby 中的 module_function 和 extend self异同的文章就讲到这里了,如果你想了解更多关于Ruby 中的 module_function 和 extend self异同的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com