Project1

标题: 为什么定义过的方法调用还是显示NoMethodError? [打印本页]

作者: 受pia专用ID    时间: 2012-1-21 20:02
标题: 为什么定义过的方法调用还是显示NoMethodError?
module Math
  def a(s)
    p s
  end
end
Math.a("s") =>NoMethodError
说什么Math模块里没有定义a方法,为什么?dsu_plus_rewardpost_czw
作者: 零の使魔    时间: 2012-1-21 20:16
本帖最后由 零の使魔 于 2012-1-21 20:25 编辑
  1. module Math
  2.   def self.a(s)
  3.     p s
  4.   end
  5. end
复制代码
要这么写哦!

@受pia专用ID
补充:如果你想偷懒随时想调用a这个定义,直接
def a(s)
p s
end

(不用成为Math的方法了)���
作者: 第七水螰    时间: 2012-1-21 23:51
普通情況下 def 定義的是實例方法,當在方法定義時指定了方法接收者(比如 self)時就是在定義單例方法。所以 def a 是 Math 的實例方法,def self.a 是 Math (這個 Module 對象)的單例方法。sin 同時是 Math 的實例方法和單例方法,所以兩種方式調用都可以,但它們卻是兩個不同的方法,元編程修改其中一個不會影響另一個。Object 從 Kernel mixin 的大量方法都是這種形式。

為了避免重複定義兩個相同的方法,你可以用 Module#module_function 將實例方法自定複製一份,並定義為單例方法:
  1. module Math
  2.   def a(s)
  3.     p s
  4.   end
  5.   module_function :a
  6. end

  7. class Foo
  8.   include Math
  9.   def bar(s)
  10.     a(s)
  11.   end
  12. end

  13. Math.a(1)
  14. Foo.new.bar(2)
复制代码

作者: zhangbanxian    时间: 2012-1-22 14:27
只要使用不带参数的module_function,以后定义的方法都会默认为模块方法,像这样
  1. module Math
  2. module_function
  3.   def a(s)
  4.     p s
  5.   end
  6. end
复制代码

作者: 忧雪の伤    时间: 2012-1-22 20:32
本帖最后由 忧雪の伤 于 2012-1-22 20:32 编辑
  1. class Math
  2.   def foo
  3.   end
  4.   def self.bar
  5.   end
  6. end
  7. Math.new.foo
  8. # => nil
  9. Math.bar
  10. # => nil
  11. Math.foo
  12. # => Error
复制代码

大致的区别就是这样。




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1