查看完整版本: 自定义Object方法时,缺省的访问权限是什么?

vintager 2008-7-3 11:23

自定义Object方法时,缺省的访问权限是什么?

def pstring=(s)
  puts s
end

self.pstring="This is a string"
结果为This is a string

如果这样
def pstring
  puts "this is a string"
end

self.pstring
报错D:/netbeans/ruby/RubyApplication10/lib/main.rb:5: private method `pstring' called for main:Object (NoMethodError)

修改为
def pstring
  puts "this is a string"
end

public :pstring

self.pstring
输出this is a string

难道带=的方法和不带=的方法访问权限不同吗?
另外还有一个不明白的问题,方法的访问权限是private,那在当前对象内部应该也是可以访问的啊,为什么会报错?

黑马 2008-7-3 15:23

查了一下源代码,时间短,没有找到实际能证明的代码,根据我的理解,如下:
首先,要明白这几个ruby的原理
1、默认(包括你所用的定义方法)在顶层定义的都是[color=Red]private[/color]的[color=Red]实例[/color]方法
2、private方法是不允许指明接收者的,其接收者只能是隐含的self

我认为,其实,这是ruby语法的一个障碍(欢迎大家砸我呀,如果说的不对)
举个例子来说:

def x11
puts "in x11"
end

def x11=(t)
  puts t
end
x11
x11="ddd"
当前定义了两个方法,都是private的,你可以puts self.private_methods.sort 看到
那为什么
x11可执行,self.x11不能执行了? 上面已有解释,调用对象所属类的实例方法是不能加self的,因为,ruby中的private很微秒,它与java等都不同。它是说:“它只能在当前对象的上下文中被调用——不可能直接访问其他对象的私有文法,即便它与调用者都属同一个类的对象”,加了self,表示调用self中的那个private方法,即便self还是指向自己,也被ruby理解为,调用了“别”的对象的私有方法
可为什么self.x11=就能执行了?因为,如果不加self,  那就等于执行 x11="ddd",这句实际上ruby优先作为给x11赋值定义变量来处理,因此为了明确表示是调用一个实例方法,所以用 self.x11="ddd",ruby又接受了这个使用方法。不知道是我的理解有误,还是ruby的灵活语法给自己带来了一个问题,它的关于private方法的说明看起来也并不那么“正确”了。可能也是没办法中的办法吧。
欢迎讨论。

vintager 2008-7-3 16:17

谢谢,你的解释不一定正确,但还是有一定道理的,我就暂时这样理解了,呵呵
另外再问一个问题:是不是=结尾的方法只能有一个参数?

xavier 2008-7-3 17:56

事实上如果你传入两个参数,他会把所有的参数合成一个数组[code]a = 0
def method=(x)
  a = x
end

method= 12,34
p a     #=>[12,34][/code]

黑马 2008-7-3 22:52

楼上的调用是不对的,你可以去试一下,你的代码跑不起来的,p a的结果不是[12,34]
因为你用  method=12,34 语句实际上是申请了一个method变量,而不是调用method=方法,如果你不信,你可以跟踪代码执行看看有没有调用method=方法。
我测试的结果是,以=结尾的目前只能接受一个参数。原因,目前不得而知,有待看源码。不过我们可以猜测。以=结尾的方法在java中叫setter方法,功能是用于对一个属性赋值。我想ruby的这种设计应该是实现java中的setter方法,所以,可能是内部作了处理,包括上面所讨论的,它以self.来作为方法接受者也是特例。
上面我所说的两点,:1、self.x11= 中用了self,有悖它的private的定义,2、=方法只接受一个参数中我所阐述的观点不作为我最终的肯定的说法,目前还没有找到底层的实际证明。抛砖引玉,欢迎大家讨论

vintager 2008-7-4 11:27

黑马兄,你真是强人,谢谢你了

黑马 2008-7-4 14:21

[quote]原帖由 [i]vintager[/i] 于 2008-7-4 11:27 发表 [url=http://www.ruby-lang.org.cn/forums/redirect.php?goto=findpost&pid=17575&ptid=5463][img]http://www.ruby-lang.org.cn/forums/images/common/back.gif[/img][/url]
黑马兄,你真是强人,谢谢你了 [/quote]
算不上,只是喜欢去捣鼓。
你也很不错,能发现这个问题。

xavier 2008-7-4 21:05

[quote]原帖由 [i]黑马[/i] 于 2008-7-3 22:52 发表 [url=http://www.ruby-lang.org.cn/forums/redirect.php?goto=findpost&pid=17563&ptid=5463][img]http://www.ruby-lang.org.cn/forums/images/common/back.gif[/img][/url]
楼上的调用是不对的,你可以去试一下,你的代码跑不起来的,p a的结果不是[12,34]
因为你用  method=12,34 语句实际上是申请了一个method变量,而不是调用method=方法,如果你不信,你可以跟踪代码执行看看有没有调 ... [/quote]
是的,可能是当时在irb里写的时候前面某一个地方a被赋值了,而我给忘了......
我已经不是第一次犯这个错误了
[size=5][color=Blue]以后用irb需谨慎[/color][/size]

xavier 2008-7-6 08:50

修改如下。[code]$a = 0
def method=(x)
  $a = x
end

self.method= 12,34
p $a[/code]
页: [1]
查看完整版本: 自定义Object方法时,缺省的访问权限是什么?