2016-10-21 4 views
0

Этот метод (из тестов SOM) опирается на Smalltalk не локальные возвращения. Есть ли способ получить такие же результаты без них?Smalltalk: лучше всего избегать нелокальных возвратов? Алгоритм rewrite

placeQueenNonLocalReturn: c 
    1 to: 8 do: [ :r | 
     (self row: r column: c) 
      ifTrue: [ 
       queenRows at: r put: c. 
       self row: r column: c put: false. 
       (c = 8) ifTrue: [ ^true ]. 
       (self placeQueen: c + 1) ifTrue: [ ^true ]. 
       self row: r column: c put: true ] ]. 
    ^false 
! 

Примечания (другой вопрос, но связанное): Можно ли изменить этот код, не зная ничего о звонивших и вызываемых методах? Я думаю, это должно дать лучшее понимание цели, но не должен ли этот метод быть автономным в отношении моего вопроса?

+0

«но не должен ли этот метод быть автономным?» Важная часть описывает интерфейс --- какие аргументы он принимает (что очевидно из кода), и каково значение повторения 'false' vs' true', что не особенно ясно. –

ответ

2

Да, это возможно. Вы используете нелокальный возврат только для быстрого перехода из цикла 1 в: 8 do:. Вы можете легко написать цикл с другим синтаксисом, как:

exit := false. 
row := 1. 
[row < 9 andNot: [exit]] whileTrue: [ (self row: r column: c) 
      ifTrue: [ 
       queenRows at: r put: c. 
       self row: r column: c put: false. 
       c = 8 ifTrue: [ exit := true ] 
         ifFalse: [ (self placeQueen: c + 1) 
            ifTrue: [ exit := true ] 
            ifFalse: [self row: r column: c put: true ] ] ]. 
^exit 

Обратите внимание, что вызов placeQueen: в петле, кажется, рекурсивный, может быть селектор вашего метода является неправильным.

Я не понимаю, что вы имеете в виду «знать о вызывающих и вызываемых» ... Я использовал в основном синтаксический переписывающий код. То же самое о самоконденсации. Этот метод не является самодостаточным, он кажется частью решения проблемы 8 Queen, но полагается на (self row: r column: c), чтобы проверить правильность места для новой королевы.

+0

Спасибо за ответ. Хотя не на 100% правильно (строка vs r и строка не увеличиваются), это то, что я искал. –

+0

Ах, да @JorgeAgra. Я немного небрежен при написании кода ¨ в воздухе, потому что мы привыкли пытаться проверить все, что мы пишем, и воспользоваться компилятором и отладчиком ... но в этом случае я пропустил часть и был слишком ленив написать остальное на изображении –

0

Давайте исправим недоразумение. Код, как показано, не содержит любые нелокальные возвращения, поэтому он не может полагаться на эту функцию.

Показанные результаты - это всего лишь нормальные возвращения - они возвращают результат обратно вызывающему абоненту. Нелокальное возвращение относится к случаю, когда значение возвращается куда-то, кроме вызывающего.

Таким образом, нет причин избегать показанных результатов,