load和require有什么不同?
include和extend有什么不同?
self是什么?
MatchData中的begin、end分别返回什么?
重定义同一个类时,意味着对原有定义进行补充,不会覆盖原来的定义。而重定义方法时,则会覆盖原有定义。
从1.6版本开始出现类变量。类变量名前都带有`@@'。
class Foo
@@F = 0
def foo
@@F += 1
print @@F, "\n"
end
end
在1.4以前的版本中,使用容器类(Array、Hash等)来代替类变量。
class Foo
F = [0]
def foo
F[0] += 1
print F[0], "\n"
end
end
class Foo
@a = 123 # (1)
def foo
p @a # (2) ... 123でなくnilになる。
end
end
(1)是类的实例变量、(2)是通常的实例变量。(2)属于Foo类的实例,而(1)属于类对象Foo(Class的实例)。
不能在实例方法中直接访问类的实例变量。
因此上面的实例变量尚未初始化,其值为nil。
特殊方法是指某实例所特有的方法。
通常这么使用。
foo = Foo.new def foo.hello print "Hello\n" end foo.hello
若想向类中添加方法,却又不想生成子类时,可以使用特殊方法。
Java程序员可能会觉得它很像inner class。
类方法就是指类的特殊方法。上面我们提到,特殊方法是归属于某对象的方法,那么这里所说的“类的特殊方法”将作何解释呢?其实Ruby中有一个“元类”的概念。它是Class类的实例,同时又被所有的类所共有。类方法就定义在这个元类中。
从形式上看,将类名当作被调的方法就是类方法。
下面,我们就在Class类的Foo实例中添加一个特殊方法。
class Foo
def Foo.test
print "this is foo\n"
end
end
像这样来调用它。
Foo.test
您有没有注意到什么?
对了,这就是所谓的类方法。
当然了,Class中所定义的方法也可以用作类方法。
上面我们提到了特殊方法。
简单说来,在Ruby中可以向对象(实例)中添加方法。
进一步讲,如果您想像操作类那样来操作对象时,该怎么办呢?
可千万别说您没这么想过(^^;
使用特殊类的话,您就可以做到这一点。
class Foo
def hello
print "hello.\n"
end
end
foo = Foo.new
foo.hello
#=> hello.
class << foo
attr :name, true
def hello
print "hello. I'm ", @name, ".\n"
end
end
foo.name = "Tom"
foo.hello
#=> hello. I'm Tom.
多棒呀。
好了,现在要问问题了
问题
如果不使用private_class_method的话,能不能将类方法变成private呢?
解答: 类方法就是类的特殊方法。
所以我们可以耍个小花招,这么处理它。
class Foo
# ...
end
class << Foo
def class_method
print "class method\n"
end
private :class_method
end
Foo.class_method #=> Error
定义特殊方法时,既可以像上面这样在特殊类中加以定义,也可以直接使用def obj.method来完成定义。
另外,您还可以在模块中定义特殊方法(而且是private方法)。
定义模块函数时,它们既是模块的特殊方法,同时又是private类型。例如,您既可以这样
Math.sqrt(2)
来调用它,又可以这样
include Math sqrt(2)
使用include来调用它,的确十分方便。
若您想把某方法定义成模块函数时,可以在模块定义中添加如下代码
module_function :method_name
即可完成定义。
模块不能生成实例,而类不能被include。
在类(模块)中include模块之后,就可实现类似于多重继承的Mix-in功能。它与父类子类之间的这种直接继承关系有所不同,内含模块的类与该模块之间存在is_a?的关系。
您在前者中可以直接使用常数,而在后者中则必须指定类名才行。
load和require有什么不同?load只能加载用Ruby编写的源文件(*.rb)。
require还可以加载*.o文件。另外,一旦require某文件之后,即使再次require也不会进行加载。
加载路径也有所不同。
include和extend有什么不同?include负责将module插入到类(模块)中,这样就能以函数的形式来调用方法;而extend负责将module插入到对象(实例)中,这样就添加了特殊方法。
self是什么?self是指执行方法的主体本身。在函数形式的方法中,是把self当作被调的。
begin、end分别返回什么?它们作用于$~,分别返回$0、$1等原来字符串的开始位置和终止位置。请参考展开标签中的例子。
如果我有classname = "SomeClass"时,如何生成SomeClass类的实例呢?主要有两个解决方法。
第1种方法既简单又可以处理嵌套类(Net::HTTP等),但如果在CGI环境中滥用它的话,将十分危险。
而第2种方法却又无法处理嵌套类的问题。但如果进行以下处理的话,就可以处理嵌套类了。
# 如果只考虑Ruby 1.8之后的版本的话,可以这样
c = classname.split(/::/).inject(Object) {|c,name| c.const_get(name) }
c.new
# 若想兼顾Ruby 1.6的话,则需要
c = Object
classname.split(/::/).each do |name|
c = c.const_get(name)
end
c.new