查看: 1675|回复: 4

[已经解决] 为什么定义过的方法调用还是显示NoMethodError?

[复制链接]
梦石
0
星屑
50
在线时间
58 小时
注册时间
2011-8-21
回帖
25
发表于 2012-1-21 20:02:57 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有账号?注册会员

×
module Math
  def a(s)
    p s
  end
end
Math.a("s") =>NoMethodError
说什么Math模块里没有定义a方法,为什么?
梦石
0
星屑
50
在线时间
132 小时
注册时间
2012-1-21
回帖
495
发表于 2012-1-21 20:16:09 | 显示全部楼层
本帖最后由 零の使魔 于 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的方法了)���

点评

这样的话include就不能用了呀。不知为什么,sin方法不管是先include再sin还是直接Math.sin都可以。 module Math def self.a(s) p s end end include Math a("s") =>ERROR   发表于 2012-1-21 20:19
具体什么原因别问我……  发表于 2012-1-21 20:16
心情大好呢
回复

使用道具 举报

梦石
0
星屑
50
在线时间
163 小时
注册时间
2011-11-12
回帖
56
发表于 2012-1-21 23:51:40 | 显示全部楼层
普通情況下 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)
复制代码
回复

使用道具 举报

梦石
0
星屑
50
在线时间
270 小时
注册时间
2010-2-4
回帖
1296
发表于 2012-1-22 14:27:58 | 显示全部楼层
只要使用不带参数的module_function,以后定义的方法都会默认为模块方法,像这样
  1. module Math
  2. module_function
  3.   def a(s)
  4.     p s
  5.   end
  6. end
复制代码
好歹当年也当过大魔王过,orz
回复

使用道具 举报

虚構歪曲

梦石
0
星屑
354
在线时间
1196 小时
注册时间
2010-12-18
回帖
3842

贵宾

发表于 2012-1-22 20:32:09 | 显示全部楼层
本帖最后由 忧雪の伤 于 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
复制代码

大致的区别就是这样。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部