新手问题 编写 Gem 的时候报错 undefined method [已解决]

jiyinyiyong · 2015年04月24日 · 最后由 jiyinyiyong 回复于 2015年04月24日 · 4161 次阅读

模块内部的局部变量引用跟其他动态语言差别么?

➤➤ ruby -v
ruby 2.0.0p481 (2014-05-08 revision 45883) [universal.x86_64-darwin14]
➤➤ uname -v
Darwin Kernel Version 14.3.0: Mon Mar 16 23:12:31 PDT 2015; root:xnu-2782.20.48
➤➤ bundle gem a-b
      create  a-b/Gemfile
      create  a-b/Rakefile
      create  a-b/LICENSE.txt
      create  a-b/README.md
      create  a-b/.gitignore
      create  a-b/a-b.gemspec
      create  a-b/lib/a/b.rb
      create  a-b/lib/a/b/version.rb
Initializing git repo in /Users/chen/Drafts/ruby/a-b
➤➤ tree
.
├── Gemfile
├── LICENSE.txt
├── README.md
├── Rakefile
├── a-b.gemspec
└── lib
    └── a
        ├── b
        │   └── version.rb
        └── b.rb

3 directories, 7 files

Rakefile

require "bundler/gem_tasks"

require 'a/b'

desc 'show'
task 'show' do
  A::B::show 'demo'
end

lib/a/b.rb

require "a/b/version"

module A
  module B
    def B.show(a)
      p "in b show a:", a
      xmethod a
    end

    def xmethod(a)
      p "in x show a", a
    end
  end
end

运行时候报错了:

➤➤ rake show
"in b show a:"
"demo"
rake aborted!
NoMethodError: undefined method `xmethod' for A::B:Module
/Users/chen/Drafts/ruby/a-b/lib/a/b.rb:7:in `show'
/Users/chen/Drafts/ruby/a-b/Rakefile:7:in `block in <top (required)>'
Tasks: TOP => show
(See full trace by running task with --trace)
def self.xmethod(a)
  p "in x show a", a
end

方法调用要跟上接收者,如果没有就默认是当前对象 self,除非是私有方法。 这里你调用 xmethod,没有接受者,而 xmethod 也不是私有方法,所以接受者就是当前对象 self,此时当前对象是 A::B,但 xmethod 是实例方法,所以会报错 undefined method ’xmethod‘ for A::B:Module,

解决方法: 1,如 #1 2,xmethod 定义为私有方法

#2 楼 @jyootai thx. 这么说是我对 module 用法理解错了, 我以为 module 内部只是作用域,实际上是类似 class 的...表?..对象?...之类的

改成这样然后成功了..

require "a/b/version"

module A
  module B
    def B.show(a)
      p "in b show a:", a
      xmethod a
    end
  end
end

def xmethod(a)
  p "in x show a", a
end
需要 登录 后方可回复, 如果你还没有账号请 注册新账号