2016-06-11 91 views
1

我想写这将导致一个RSpec的测试像这样通过一个方法:删除项目不还

it "starts the thing and move on" do 
    class.method_1("Name One") 
    class.method_1("Name Two") 
    expect(class.method_2).to eq "Some string Name One" 
    expect(class.method_3).to eq ["Name Two"] 
end 

method_1只是增加了一个名字到一个数组,并method_3返回数组(在initialize方法定义):

def method_1(name) 
    @array << name 
end 

def method_3 
    @array 
end 

我想这将是相当简单的内插@array[0]到字符串并使用@array.delete_at(0)修改数组。像这样:

def method_2 
    p "Some string #{@array[0]}" 
    @array.delete_at(0) 
end 

但是该方法返回"Name One"而不是字符串。如果我注释掉删除代码,该字符串会正确返回,但我的数组尚未修改。我已经在Ruby文档很长一段时间,但#shift有关于返回已删除的项目相同的问题。

我几乎可以肯定我已经复杂了 - 我错过了什么?

回答

1

您可以向下塌陷这一切更常规的Ruby这样的:

class MyTestClass 
    attr_reader :array 

    def initialize 
    @array = [ ] 
    end 

    def push(s) 
    @array << s 
    end 

    def special_shift 
    "Some string #{@array.shift}" 
    end 
end 
在使用方面

然后:

it "starts the thing and move on" do 
    my_thing.push("Name One") 
    my_thing.push("Name Two") 
    expect(my_thing.special_shift).to eq "Some string Name One" 
    expect(my_thing.array).to eq ["Name Two"] 
end 

使用名称,如0123与Ruby约定一致的和shift使得方法的目的和行为更容易理解。

当谈到你的实现method_3时,你忘记了你可以在#{...}块内嵌入任何你想要的东西,甚至是修改东西的方法。 p方法用于显示,它不会返回任何东西。要返回某些东西,您需要将其作为最后一项评估(隐式)或使用return(显式)。

+0

我不敢相信我没有想到将'@ array.shift'集成到代码的打印行中。感谢您的帮助和对退货的澄清。你说得对,'method_3'可以很容易地成为内联块,但是之前的测试需要定义。 –

+0

其他编程语言对可以插入的内容有严格的限制,所以如果你没有考虑这样做可以。可以是你永远不会想到的挑战。在Ruby中,您可以在其中插入*任何有效的代码块。 – tadman

0

更改method_2以下,以获得阵列背面

def method_2 
    p "Some string #{@array[0]}" 
    @array.delete_at(0) 
    @array 
end 

array#delete_if上ruby-doc.org

删除指定索引处的元素,返回该元素,或者如果零该指数超出范围。

或者使用object#tap返回自

@array = [1,2,3,4] 
#=> [1, 2, 3, 4] 
@array.tap {|arr| arr.delete_at(0)} 
#=> [2, 3, 4] 
+0

'tap'在这里相当笨重。 – tadman

+0

我正在寻找一种方法来从数组中删除索引,并返回已修改的数组,而不是已删除的项目。到目前为止,我找不到任何东西,除了这个.tap例子。 @tadman,你能向我解释一下,龙头怎么样? – Ekkstein

+0

为了获得单线解决方案,“点击”没有任何优势。这里的两行版本非常好,更容易理解。 – tadman