Ruby:类方法和初始化

时间:2013-09-04 00:32:01

标签: ruby rspec

目前正在努力通过一个rspec教程,并且非常感谢一些澄清。

代码是:

class Book

    attr_reader :title

    def initialize(title=nil)
        @title = title = title && title.capitalize!
    end

    def title=(new_title = nil)
        @title = new_title && new_title.each do |word|
        word.capitalize!
    end
end

两个问题:

  1. 为什么有两组@title(即:为什么在initializetitle中定义为设置=不同的东西)?

  2. 为什么title方法之后有=?如果我不使用=

  3. ,代码会中断

    编辑:出于我的rspec教程的目的,这是我最终尝试过的代码

    class Book
        attr_accessor :title
    
        def initialize(title = nil)
            @title = title
        end
    
        def title=(book_title = nil)
            @title = book_title.capitalize 
        end
    end 
    

    我最初的问题是使用title =方法。最后,我遇到了一个解释什么方法=函数的线程。如果你想为一个类方法中的某个东西分配一个值是必要的(至少这是我在这一点上的理解。请随意纠正我。)

    我也很感激这个新代码中的任何提示。

2 个答案:

答案 0 :(得分:1)

让我们分析一下:

attr_reader :title

这里我们基本上定义了方法:

def title; @title; end

返回实例变量@title

def initialize(title=nil)
    @title = title = title && title.capitalize!
end

这里我们定义一个0-1参数构造函数,可以简化为:

def initialize(title=nil)
    title && @title = title.capitalize
end

事实是构造函数中的title是参数变量而不是titletitle=方法,因此后面定义的title=方法永远不会在这里调用。请注意,&&此处用于short-circuit evaluation

def title=(new_title = nil)
    @title = new_title && new_title.each do |word|
    word.capitalize!
end

这里我们实际上有两个语法错误:第一个是String的错误(我假设它是 title 的类型,因为它似乎调用String#capitalize!后来)没有each方法。写这篇文章的人可能首先代表String#each_charString#split

第二个错误是each之后的阻止没有被end关闭。

现在假设这个版本:

def title=(new_title = nil)
    @title = new_title && new_title.split(' ').each { |word| word.capitalize! }.join(' ')
end

title=只会将title分配给@title变量,原因与之前相同(短路评估),可以简化为:

def title=(new_title = nil)
    new_title && @title = new_title
end

答案 1 :(得分:0)

在构造类的实例时调用initialize方法。 @title = ...设置了@title的初始值。

当有人随后在类的实例上设置title的值时,将调用title=方法。然后相应地调整@title的值。有关详细说明,请参阅Ruby Accessors

举个例子:

book = Book.new       # calls initialize
book.title = 'foo'    # calls title=