2017-02-15 9 views
0

Rubyで二重リンクリストを構築して操作するプログラムをビルドしようとしています。リンクリストからノードを削除しようとしていて、エラーメッセージを理解していない

これまでのところ私はリストを作成したことを伝えるテストを満足させることができましたが、deleteメソッドを動作させるのに苦労しています。

Failure/Error: llist.delete(n3) 
      NameError: 
     undefined local variable or method `current' for #<LinkedList:0x007f85a49ae9b8> 
     Did you mean? current 

私は、これはこれは

require_relative 'node' 

class LinkedList 
    attr_accessor :head 
    attr_accessor :tail 
    bob = [] 
    current = nil 
    # This method creates a new `Node` using `data`, and inserts it at the end of the list. 
    def add_to_tail(node) 
    if(@next) 
     @tail.next = node 
    else 
     @tail= node 
    end 
    end 
# This method removes `node` from the list and must keep the rest of the list intact. 
    def delete(node) 
    current.next [email protected] 
    if current.node = node 
     @head =current.next 
    else 
     while (current.next != nil)&&(current.next.node != val) 
     current = current.next 
     end 
     unless current.next == nil 
     current.next =current.next.next 
     end 
    end 

    end 

linkedlist.rbファイルである方法

を定義していますかなり確信しているにもかかわらず:

は今、私のRSpecのテストでは、私に告げる保ちます Nodeクラスを設定するコンパニオンファイル

class Node 
    attr_accessor :next 
    attr_accessor :data 

    def initialize(data) 
    @data = data 
    #@next = nil 
    end 
end 

これらはルビークラススコープ変数は、二重@@で設定されているが、私はあなたがクラススコープ内の現在とボブ定義されている

include RSpec 

require_relative 'node' 
require_relative 'linked_list' 

RSpec.describe LinkedList, type: Class do 
    let(:n1) { Node.new("Rob") } 
    let(:n2) { Node.new("Ben") } 
    let(:n3) { Node.new("Mike") } 
    let(:llist) { LinkedList.new } 

    describe "#add_to_tail" do 
    it "adds a Node to the tail" do 
     llist.add_to_tail(n1) 
     expect(llist.tail).to eq n1 
     llist.add_to_tail(n2) 
     expect(llist.tail).to eq n2 
    end 
    end 
    describe "#delete" do 
    before do 
     llist.add_to_tail(n1) 
     llist.add_to_tail(n2) 
     llist.add_to_tail(n3) 

it "removes the correct node of a list properly" do 
     llist.delete(n1) 
     expect(llist.head).to eq n2 
     llist.delete(n3) 
     expect(llist.tail).to eq n2 
    end 

答えて

2

に合格しようとしていますRSpecのテストです。しかし、これは複数のリンクされたリストを使うときに問題を引き起こすので、この場合はクラス変数を使いたくないでしょう。したがって、最善の方法は、LinkedListインスタンスの@currentおよび@bobインスタンス変数を設定することです。これに

変更電流とボブ:私は次の操作を行うことをお勧めattr_accessorが何

attr_accessor :current 
attr_accessor :bob 

を、@currentインスタンス変数を作成し、またあなたのための2つのメソッド、ゲッターcurrentとを規定していますセッターcurrent=

ゼロと配列にそれらを設定するための次のステップは、initializeメソッドを使用して、あなたのLinkedListクラスにこれを追加することです:

def initialize(*args) 
    @current = nil 
    @bob = [] 
end 

@currentインスタンスが作成されると、それはすでに設定されますが、 nilになるので、初期化の最初の行は実際には冗長です。表示目的で追加して、現在のコードと比較して何が起こっているのかを簡単に確認できます。

+1

クラスレベルのインスタンス変数にはプレフィックス「@@」が付いていますが、これらを使用すると問題が発生する可能性があります。それが必要ならば、クラススコープで定義されたクラスインスタンス変数を使用する方が良いでしょう。 – tadman

+0

実際にはインスタンス変数を使用することをお勧めしますが、クラスレベルのインスタンス変数とクラス変数は異なります。クラス変数は@@で設定されます。クラスレベルのインスタンス変数は単一の@で設定されますが、 'class << self;のようなものを持つクラス。 attr_accessor:現在の;そのクラスは継承されたクラスの変数を分割しますが、同じクラスのインスタンスは依然として問題になります。 stadard @でインスタンス変数を設定します。私はちょっとやっかいですが、Class、Class-leve instancel、インスタンス変数が異なる点を確認したかったのです。 –

+1

ここで非常によく説明されています:http://www.railstips.org/blog/archives/2006/11/18/class-and-instance-variables-in-ruby/ –

関連する問題