2014-02-09 2 views
0

Я работаю над некоторыми проблемами домашней работы для рубинового курса, и у меня были некоторые проблемы с моим ответом. В принципе мне нужно создать программу, которая может удовлетворить эти условия:Ruby: Proc для изменения строки

describe "reverser" do 
it "reverses the string returned by the default block" do 
    result = reverser do 
    "hello" 
    end 
    result.should == "olleh" 
end 

it "reverses each word in the string returned by the default block" do 
    result = reverser do 
    "hello dolly" 
    end 
    result.should == "olleh yllod" 
end 
end 

Я озадачил вместе некоторый код, который я чувствую, должен удовлетворять эти условия:

reverser = Proc.new do |string| 

words = string.split(/\b/) 

answer = '' 

i = 0 
while i < words.count 
    answer = answer + words[i].reverse 
    i += 1 
end 
answer 
end 


def reverser 
yield 

end 

Но когда я запускаю грабли, моя ошибка говорит я не выполнил первое условие.

expected: "olleh" 
got: "hello" 

Есть ли что-то, что мне не хватает? У меня просто нет правильного понимания процессов?

Этот вопрос задан в какой-то форме членом, названным pete, и довольно хорошо ответил другой пользователь по имени mind.blank. Это источник:

Beginner RSpec: Need help writing Ruby code to pass RSpec tests (Silly Blocks exercise).

Код mind.blank был прост и работал правильно, но я не просто хочу его копировать, не понимая, почему мой не работает. Заранее благодарю за любую помощь.

ответ

1

Так - то, что у вас есть локальная переменная с именем «реверса» и метод под названием «реверс» (который будет «тень» реверсор местный)

Ваш код никогда не выполняется.

Итак - то, что вы хотите сделать, - это взять результат урожая и выполнить обратную операцию. (Оставляя в стороне, как странно, что требование на мгновение.)

def reverser 
    string = yield 
    # ... all of your reverser code ... 
end 

Теперь кружась назад вокруг - это причудливый способ использовать блок. Блок предназначен для передачи дополнительного выполнения методу, а не для передачи ему аргумента. Итак, если вы хотите сказать, что для каждого символа в реверсе (обратном?) Выполняется обратный вызов, который будет правильным использованием доходности.

Кроме того, Ruby уже имеет метод String#reverse - так что проще всего сделать, чтобы ваши тесты прошли, это что-то типа.

def reverser 
    (yield).split(/\b/).map(&:reverse).join 
end 
+0

мажор. ты прав. – prater

+0

Спасибо за подсказку. Это был ответ, что парень из другой темы опубликовал. Я просто не хотел красть его код, не зная почему. Но теперь я понимаю это немного больше. – zethsaber

1

Ваш reverser прок делает работу, если вы говорите reverser.call('abc') (или reverser['abc'] или reverser.('abc')), то вы получите ожидаемый 'cba' назад.

Проблема заключается в том, что ваш тест не использует ваш reverser proc, он использует ваш метод reverser. Это призыв к reverser метода с блоком:

result = reverser do 
    "hello" 
end 

но reverser метод ничего интересного не делает, он просто дает блоку:

def reverser 
    yield 
end 

так result заканчивает тем, значение блока, и это 'hello'.

Либо проверить процедурный:

it "reverses the string returned by the default block" do 
    result = reverser['hello'] 
    result.should == "olleh" 
end 

или переместить кишки прок в в метод reverser и проверить, что:

def reverser 
    string = yield 
    words = string.split(/\b/) 
    answer = '' 

    i = 0 
    while i < words.count 
    answer = answer + words[i].reverse 
    i += 1 
    end 
    answer 
end 

Есть более эффективные способы написать этот код (например, words.map(&:reverse).join вместо while), но ваша логика реверсирования работает, вам просто нужно убедиться, что вы называете нужную версию.

+0

Большое спасибо. Таким образом, мое понимание rspec, похоже, немного теневое. Я должен признать, что я расстраивался, но ваше объяснение прояснилось. Я бы поднял вас, ребята, но я новичок на сайте: D. Еще раз спасибо – zethsaber

+1

Не беспокойтесь. Поддержки, которые хотят понять, что происходит, а не слепо натыкаться на чужой код, это хорошее отношение. –

0

Этот код будет обратной последовательности, данные метода как блок

def reverser 
    # yield is the string given in the block 
    words = yield.split(' ') 
    final = [] 
    words.each do |word| 
     final.push(word.reverse) 
    end 
    final.join(' ') 
end 
Смежные вопросы