describeとitのスコープ

せっせせっせとspecファイルを書いていたら、describeとitのスコープが気になりだしてきた。
ちょちょいとググってみたら同じ事が気になった人がいらっしゃいました

自分でもやってみる。

とりあえず、こんなspecを書いてみました

puts "Outside: "
puts "  self        # => #{self}"
puts "  self.class  # => #{self.class}"

describe "Fruit" do
  puts "  => describe Fruit: "
  puts "     self       # => #{self}"
  puts "     self.class # => #{self.class}"
  puts "     superclass # => #{superclass}"

  it "Apple" do
    puts "     => it Example 1 of Fruit:"
    puts "        self       # => #{self}"
    puts "        self.class # => #{self.class}"
  end

  it "Orange "do
    puts "     => it Example 2 of Fruit:"
    puts "        self       # => #{self}"
    puts "        self.class # => #{self.class}"
  end

  describe "Banana" do
    puts "  => describe Fruit::Banana "
    puts "     self       # => #{self}"
    puts "     self.class # => #{self.class}"
    puts "     superclass # => #{superclass}"

    it "Yellow" do
      puts "     => it Example 1 of Fruit::Banana"
      puts "        self       # => #{self}"
      puts "        self.class # => #{self.class}"
    end
  end
end

describe "Vegetable" do
  puts "  => describe Vegetable: "
  puts "     self       # => #{self}"
  puts "     self.class # => #{self.class}"
  puts "     superclass # => #{superclass}"

  it "Tomato" do
    puts "     => it Example 1 of Vegetable:"
    puts "        self       # => #{self}"
    puts "        self.class # => #{self.class}"
  end

  it "Potato" do
    puts "     => it Example 2 of Vegetable:"
    puts "        self       # => #{self}"
    puts "        self.class # => #{self.class}"
  end
end

やってる事は、ほぼ一緒。descibeの入れ子も入れてみた。
で、こいつを2つ用意して、specにかけてみる。

Outside:
  self        # => main
  self.class  # => Object
  => describe Fruit:
     self       # => Spec::Example::ExampleGroup::Subclass_1
     self.class # => Class
     superclass # => Spec::Example::ExampleGroup
  => describe Fruit::Banana
     self       # => Spec::Example::ExampleGroup::Subclass_1::Subclass_1
     self.class # => Class
     superclass # => Spec::Example::ExampleGroup::Subclass_1
  => describe Vegetable:
     self       # => Spec::Example::ExampleGroup::Subclass_2
     self.class # => Class
     superclass # => Spec::Example::ExampleGroup
Outside:
  self        # => main
  self.class  # => Object
  => describe Fruit:
     self       # => Spec::Example::ExampleGroup::Subclass_3
     self.class # => Class
     superclass # => Spec::Example::ExampleGroup
  => describe Fruit::Banana
     self       # => Spec::Example::ExampleGroup::Subclass_3::Subclass_1
     self.class # => Class
     superclass # => Spec::Example::ExampleGroup::Subclass_3
  => describe Vegetable:
     self       # => Spec::Example::ExampleGroup::Subclass_4
     self.class # => Class
     superclass # => Spec::Example::ExampleGroup
     => it Example 1 of Fruit:
        self       # => #<Spec::Example::ExampleGroup::Subclass_1:0xb79798cc>
        self.class # => Spec::Example::ExampleGroup::Subclass_1
.     => it Example 2 of Fruit:
        self       # => #<Spec::Example::ExampleGroup::Subclass_1:0xb7979368>
        self.class # => Spec::Example::ExampleGroup::Subclass_1
.     => it Example 1 of Fruit::Banana
        self       # => #<Spec::Example::ExampleGroup::Subclass_1::Subclass_1:0xb7978a80>
        self.class # => Spec::Example::ExampleGroup::Subclass_1::Subclass_1
.     => it Example 1 of Vegetable:
        self       # => #<Spec::Example::ExampleGroup::Subclass_2:0xb79781c0>
        self.class # => Spec::Example::ExampleGroup::Subclass_2
.     => it Example 2 of Vegetable:
        self       # => #<Spec::Example::ExampleGroup::Subclass_2:0xb7977cac>
        self.class # => Spec::Example::ExampleGroup::Subclass_2
.     => it Example 1 of Fruit:
        self       # => #<Spec::Example::ExampleGroup::Subclass_3:0xb79774a0>
        self.class # => Spec::Example::ExampleGroup::Subclass_3
.     => it Example 2 of Fruit:
        self       # => #<Spec::Example::ExampleGroup::Subclass_3:0xb7976f8c>
        self.class # => Spec::Example::ExampleGroup::Subclass_3
.     => it Example 1 of Fruit::Banana
        self       # => #<Spec::Example::ExampleGroup::Subclass_3::Subclass_1:0xb79766b8>
        self.class # => Spec::Example::ExampleGroup::Subclass_3::Subclass_1
.     => it Example 1 of Vegetable:
        self       # => #<Spec::Example::ExampleGroup::Subclass_4:0xb7975df8>
        self.class # => Spec::Example::ExampleGroup::Subclass_4
.     => it Example 2 of Vegetable:
        self       # => #<Spec::Example::ExampleGroup::Subclass_4:0xb79758e4>
        self.class # => Spec::Example::ExampleGroup::Subclass_4
.

Finished in 0.02293 seconds

10 examples, 0 failures

ちょっとわかりやすくしてみる

putsを削ると

describe "Fruit" do
  it "Apple"
  it "Orange"
  
  describe "Banana"
    it "Yellow"
  end
end

describe "Vegetable" do
  it "Tomato"
  it "Potato"
end

こんな感じですね。

実行結果を表にまとめてみた

Class名のSpec::Example::は省略してます。

describe
ファイル describe self class superclass
test_1 Fruit ExampleGroup::Subclass_1 Class ExampleGroup
test_1 Fruit::Banana ExampleGroup::Subclass_1::Subclass_1 Class ExampleGroup::Subclass_1
test_1 Vegetable ExampleGroup::Subclass_2 Class ExampleGroup
test_2 Fruit ExampleGroup::Subclass_3 Class ExampleGroup
test_2 Fruit::Banana ExampleGroup::Subclass_3::Subclass_1 Class ExampleGroup::Subclass_3
test_2 Vegetable ExampleGroup::Subclass_4 Class ExampleGroup
it(example)
ファイル describe it class
test_1 Fruit Apple ExampleGroup::Subclass_1
test_1 Fruit Orange ExampleGroup::Subclass_1
test_1 Fruit::Banana Yellow ExampleGroup::Subclass_1::Subclass_1
test_1 Vegetable Tomato ExampleGroup::Subclass_2
test_1 Vegetable Potato ExampleGroup::Subclass_2
test_2 Fruit Apple ExampleGroup::Subclass_1
test_2 Fruit Orange ExampleGroup::Subclass_1
test_2 Fruit::Banana Yellow ExampleGroup::Subclass_1::Subclass_1
test_2 Vegetable Tomato ExampleGroup::Subclass_2
test_2 Vegetable Potato ExampleGroup::Subclass_2

つまりは?

  • 実行結果を見てもわかるように、まずはそれぞれのファイルのdescribe部分がClassとして生成される。
  • describeの中にあるitはdescribeのClassのオブジェクトとして生成される。

という事ですね。

ちなみにdescribeを入れ子にした Fruit::Banana の Spec::Example::ExampleGroup::Subclass_2::Subclass_1 は Spec::Example::ExampleGroup::Subclass_2 を継承しているようです。

次回は?

今回は人がやった事をそのままやっただけなので次回は

  • ところでbeforeとafterは?
  • 変数のスコープは?

の2本でお送りいたします。