3

我已经完成了 Hartl 的 Rails 教程,但仍然存在一个困惑:我什么时候使用@variable,什么时候应该使用:variable,什么时候才是variable正确的?

这是我从教程中获取的一些示例代码:

describe "micropost associations" do
    before { @user.save }
    let!(:older_micropost) do 
      FactoryGirl.create(:micropost, user: @user, created_at: 1.day.ago)
    end
    let!(:newer_micropost) do
      FactoryGirl.create(:micropost, user: @user, created_at: 1.hour.ago)
    end
    .
    .
    .
    it "should destroy associated microposts" do
      microposts = @user.microposts.dup
      @user.destroy
      microposts.should_not be_empty
      microposts.each do |micropost|
        Micropost.find_by_id(micropost.id).should be_nil
      end
    end
  end
  .
  .
  .
end

相比于:

describe Micropost do
  let(:user) { FactoryGirl.create(:user) }
  before { @micropost = user.microposts.build(content: "Lorem ipsum") }

以下是这个(和其他代码)为我提出的一些更具体的问题:

  1. 是否@user需要@在第一个片段中,因为它是主题还是..?
  2. 我是否总是使用 声明新变量:?(实际上我很确定情况并非如此,但我不明白为什么和为什么。)
  3. 当我稍后引用我使用创建的变量时:,我会:再次使用吗?例如,如果我要执行print(:older_micropost)or print(older_micropost),有区别吗?(参见let第二个片段中的语句)。
  4. 它们在一个街区内的工作方式与在before街区外的工作方式相同吗?我发现某些代码只能在before块内部/外部工作(例如older_micropost.destroy)。

我在别处寻找过这个问题的答案,但我找不到关于 、 和什么都没有的@讨论:

编辑:这是第三段代码,这次是我自己的。我已经评论了哪些有效,哪些无效:

describe "deleting a user following" do
  let(:userid) { @user.id }
  before { print(@user.id.inspect) # this works
           @user.destroy }         # this works
  @user.destroy                    # this doesn't
  print(@user.id.inspect)          # this doesn't
  subject { other_user }
  its(:followed_users) { should_not include(userid) }
end

(显然我没有同时运行所有 4 行注释代码,我在 before 块内运行两行或在外面运行两行)

为什么这些语句只能在 before 块内工作?

4

2 回答 2

3

他混合了旧的和新的 RSpec 语法,这使得它有些混乱。

RSpec 的原始化身自始至终都使用实例变量。所以:

before { @user = User.new }

it "should be valid" do
  @user.should be_valid
end

RSpec 后来获得了使用以下方法为变量赋值的能力let

let(:user) { User.new }

it "should be valid" do
  user.should be_valid
end

let将符号作为参数并定义一个方法,该方法在引用该方法时产生指定的结果。的主要优点let是它是惰性求值的。这使您可以延迟变量设置,这在嵌套示例时效果特别好。

您可以像 Hartl 那样混合和匹配这两种范式,但这可能会让人感到困惑。最好使用一种风格或另一种风格。

@user 是否需要第一个片段中的 @ 因为它是主题或..?

它需要使用 @ 或不使用(使用let)定义,然后始终以相同的方式引用。@useruser不是一回事。

我是否总是使用 : 声明新变量?(实际上我很确定情况并非如此,但我不明白为什么和为什么。)

: 是符号的前缀。您只能在let.

当我稍后引用我使用 : 创建的变量时,我会再次使用 : 吗?例如,如果我要执行 print(:older_micropost) 或 print(older_micropost),有区别吗?(参见第二个片段中的 let 语句)。

引用变量时使用方法名称,而不是符号。所以micropost,不是:micropost

它们在前块内的工作方式与在块外的工作方式相同吗?我发现某些代码只能在前块内部/外部工作(例如,older_micropost.destroy)。

在示例正文中工作的任何代码也应该在 before 块中工作。将代码放在示例之外是行不通的,例如:

let(:user) { User.new(:name => "Phil") }

before { puts user.name } # "Phil"

it "sets the name" do
  puts user.name # "Phil"
end

puts user.name # undefined local variable or method `user' 
于 2013-02-15T04:27:07.567 回答
1

这是一个实例变量,意味着每当您需要将信息从控制器传递到视图或反之亦然时,我们通常会使用它@variable

Now:用于符号,意味着它们大部分时间类似于字符串,但在内存方面它们比简单字符串便宜,因为它一次比较整个字符串。

有关这方面的更多信息,请阅读文章http://www.robertsosinski.com/2009/01/11/the-difference-between-ruby-symbols-and-strings/

于 2013-02-14T05:46:07.583 回答