打印

[问题求助] 关于Module和include功能

关于Module和include功能

我定义了一个Module大致如下:

Module Blitz3D
  CONST_VAL = 1
  def my_method
    # something here
  end
end


然后我再

include Blitz3D


我本来想做到在代码的其它位置可以直接这样写:

my_method
print CONST_VAL


但是我现在只能在全局访问CONST_VAL(不用Blitz3D::CONST_VAL),而不能在全局访问 my_method (只能用Blitz3D.my_method ,不能直接写 my_method )。
我想知道如何才能做到使模块的常量和方法都能在全局直接访问。(是用 public 或者 alias_method 吗?那又怎么做呢?)
Many thanks!

TOP

你没有搞清类方法和实例方法的概念。
1、
 class A
   def x
    print "x"
   end
   def self.y
     print"y"
   end
  end
这个时候我们可以直接调用y 但不能直接调用x,因为x这是实例方法,y是类方法。想调用x,必须分配一个A的实例如 t=A.new 然后t.x,module
2、定义一个module
 Module M1
  def self.x
  puts "x"
  end
 def M1.y
  puts "y"
 end
 def z
   puts "z"
 end
end
这个时候,我们能M1.x M1.y调用,
如果在一个class中include了这个module
 class C1
  include M1
 end
则可 c=C1.new c.z 而c.x c.y都是不能调用的。但在C1中可M1.y 调用
原因在于, x方法是以M1定义时对象为接受者,y方法是以M1为接受者,实际上是M1的“类”方法。
3、你想要的是在“顶层”环境直接调用某个方法,那不应该定义在其它任何module或class中,而应该定义在Object中,你可以这么做
 class Object
   def x
    puts "in x"
  end
 end

 Module M1
  def x
    puts "in x"
  end
 end
 class Object
  include M1
 end
本帖最近评分记录
  • drive2me 威望 +10 谢谢! 2008-6-25 09:46
  • drive2me R币 +10 谢谢! 2008-6-25 09:46
  • drive2me 贡献 +10 谢谢! 2008-6-25 09:46
  • jiaxiao R币 +1 解答很清楚 2008-6-24 20:39

TOP

好像还是不可以……

如题。我照你说的把module加到了Object里面,但是依旧提示我method missing。

代码如下:

require 'dl/import'
module Blitz3D
  extend DL::Importable
  dlload "redist/B3D.dll"
  
  BBFALSE = 0
  BBTRUE = 1
  KEY_ESCAPE = 1
  KEY_TAB = 15
  KEY_SPACE = 57
  KEY_RETURN = 28
  KEY_LEFTSHIFT = 42
  KEY_LEFTCONTROL = 29
  KEY_LEFTALT = 56
  KEY_RIGHTSHIFT = 54
  KEY_RIGHTCONTROL = 157
  KEY_RIGHTALT = 184
  KEY_UP = 200
  KEY_LEFT = 203
  KEY_RIGHT = 205
  KEY_DOWN = 208

  extern "int bbBeginBlitz3D()"
  extern "void bbEndBlitz3D()"
  extern "void bbGraphics(int,int,int,int)"
  extern "void bbSetBlitz3DTitle(const char*,const char*)"
  extern "void bbFlip(int)"
  extern "int bbLoadImage(const char*)"
  extern "void bbDrawImage(int,int,int,int)"
  extern "void bbFreeImage(int)"
  extern "int bbKeyHit(int)"
end

class Object
  include Blitz3D
end

bbBeginBlitz3D
bbGraphics( 640, 480, 0, 2 )
bbSetBlitz3DTitle( "blitz3d.rb", "Sure to quit?" )

while BBTRUE != bbKeyHit( KEY_ESCAPE )
  img = bbLoadImage( "game.png" )
  bbDrawImage( img, 0, 0, 0 )
  bbFreeImage( img )
  bbFlip( 1 )
end

bbEndBlitz3D


我用 ruby -w b3d.rb 运行这个程序:
D:\src\ruby\blitz3d>ruby -w b3d.rb
(eval):2: warning: instance variable @SYM not initialized
(eval):2:in `bbBeginBlitz3D': undefined method `[]' for nil:NilClass (NoMethodEr
ror)
   from b3d.rb:38

看来还是不可以……
这到底是怎么回事呢?
本帖最近评分记录
  • drive2me R币 +5 继续努力,哈! 2008-6-25 09:46

TOP

顺便帮我把ruby打印出来的错误信息解释一下哈~

TOP

好好看看错误,不是说没有找到bbBeginBlitz3D这个方法,说明已经mixin入Object类了,提示没找到什么看看是不是你那个方法里面的错误了,debug一下看看。
前面一个警告是说没有初始化一个@SYM变量

TOP

可是我写成 Blitz3D.bbBeginBlitz3D 就没有问题了呀,而且运行也正常。
这个方法没有问题的。Blitz3D是一个商业库,许许多多用户都使用过的,我问了,也没有任何Bug……
到底是怎么回事啊~~
(如果你还有耐心帮我的话,我可以把整个目录都发给你的,包括我写的ruby代码和Blitz3D库文件、DLL等;无论如何都谢谢了哈

TOP

你的module中的方法是否这样定义的?
module M1
 def M1.x
  ...
 end
end

如果这么定义的,你只要require 这个文件,就可以 M1.x调用了。
如果你的module是
 module M1
    def y
    ...
    end
  end
那我上面的方法是肯定可以的。
能区别出上面两个例子的意思吧?
我们mixin一个module到一个class中,只能混入常量、类变量、实例方法, 也就是说,类方法是混入不了的

[ 本帖最后由 黑马 于 2008-6-25 22:38 编辑 ]
本帖最近评分记录
  • jiaxiao R币 +2 谢谢你的帮助,我明白了。 2008-6-27 21:41

TOP

2008-10-12 15:44 Crawled by CCBot/1.0 (+http://www.commoncrawl.org/bot.html) @38.103.63.60