Ruby 私有 attr_accessor 和意外的 nil [英] Ruby private attr_accessor and unexpected nil

查看:43
本文介绍了Ruby 私有 attr_accessor 和意外的 nil的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我经常使用 Ruby 时,我有一个坏习惯,就是把所有东西都公开而忽略隐私.不幸的是,这种无知又回来困扰着我.这是我的问题的一个更简单的版本:

Back when I used Ruby regularly, I had a bad habit of leaving everything public and ignoring privacy. Unfortunately, that ignorance is coming back to haunt me. Here's a simpler version of my problem:

class Something
    private
    attr_accessor :sneaky
    public

    def initialize
        @sneaky = 0
    end

    def test
        while sneaky < 10
            puts "#{sneaky}"
            sneaky = (sneaky + 1)
        end
    end
end

test = Something.new
test.test

这会打印出sneaky (0) 的正确值,然后在sneaky = (sneaky + 1) 处出错,说sneakynil:

This prints the correct value of sneaky (0), then errors out at sneaky = (sneaky + 1), saying that sneaky is nil:

0
test.rb:13:in `test': undefined method `+' for nil:NilClass (NoMethodError)
    from test.rb:19:in `<main>'

这是怎么回事?@sneaky 在构造函数中被设置为 0.如果它真的是 nil,那么 puts 不应该打印一个空行而不是 0 吗?

What's up with that? @sneaky's been set to 0 in the constructor. And if it really were nil, shouldn't that puts print a blank line and not a 0?

是的,将 sneaky = (sneaky + 1) 替换为 self.sneaky = splashy + 1 可以解决问题,即使 self.sneaky= 看起来像是侵犯了隐私,因为它有一个明确的接收者.显然,setter 是个例外.但是与隐私的奇怪交互意味着你不能说 self.sneaky += 1(你最终得到 test.rb:14:in 'test': private method 'sneaky' called对于#(NoMethodError)).幸运的是,我不是唯一一个认为这很奇怪的人.

Yep, replacing sneaky = (sneaky + 1) with self.sneaky = sneaky + 1 solves the problem, even though self.sneaky= looks like a privacy violation, since it has an explicit receiver. Apparently an exception is made for setters. But the weird interaction with privacy means you can't say self.sneaky += 1 (you end up getting test.rb:14:in 'test': private method 'sneaky' called for #<Something:0x000001019004c8 @sneaky=0> (NoMethodError)). Fortunately I'm not the only one who thinks that's weird.

推荐答案

foo = bar 的一种形式分配给名为 foo 的局部变量.如果要调用attr_writer,则需要使用显式接收器:self.sneaky += 1.

A form of foo = bar assigns to a local variable called foo. If you want to call an attr_writer, you need to use an explicit receiver: self.sneaky += 1.

这与 private 无关,它只是用于局部变量赋值的基本 Ruby 语法.

This has nothing to do with private, it's just basic Ruby syntax for local variable assignments.

这篇关于Ruby 私有 attr_accessor 和意外的 nil的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆