Класс, который я сейчас посещаю, требует, чтобы мы все кодировали на smalltalk (это класс дизайна). В одном из наших проектов я хочу кое-что сделать, и мне трудно найти, как это сделать. Похоже, что большинство людей модифицируют свою собственную версию smalltalk, чтобы делать то, что им нужно. Я не вправе делать это, так как это вызовет ошибку на компьютере моего профессора, если у него нет тех же встроенных методов, что и у меня.
Вот что я хочу сделать:
Случайные числа. Мне нужно создать случайное число от 1 до 1000. Сейчас я имитирую это, делая
rand := Random new.
rand := (rand nextValue) * 1000.
rand := rand asInteger.
Это дает мне число от 0 до 1000. Есть ли способ сделать это одной командой? похожий на
Random between: 0 and: 1000
И / или заявления. Этот вышибает из меня дневной свет. Я пробовал несколько разных конфигураций
(statement) and: (statement) ifTrue...
(statement) and (statement) ifTrue...
Итак, я имитирую это с помощью вложенных операторов ifTrue:
(statement) ifTrue:[
(statement) ifTrue:[...
Как правильно использовать и / или Random в smalltalk?





Проблема в том, что
(expr) and: (expr) ifTrue: aBlock
анализируется как метод and:ifTrue:. Если вы посмотрите на класс Boolean (и, в частности, на True или False), вы заметите, что ifTrue: - это просто обычный метод, и что метод и: ifTrue: не существует, однако простой и: . Чтобы было понятно, что это два сообщения, напишите
((expr) and: (expr)) ifTrue: aBlock
Для более длинных логических комбинаций обратите внимание на то, что существуют также методы and: and: and and: and: and :.
Но это неполно, поскольку and: принимает блок, как сказал Райдье. И без этого столбец будет анализироваться как унарное сообщение и впоследствии вызывать ошибку синтаксического анализа, потому что он ожидает только сообщения после него, а не полное выражение.
Что касается случайной проблемы: это зависит от того, какую версию ST вы используете. В Squeak 3.9 есть Random>>#nextInt:, который задокументирован как «Ответить на случайное целое число в интервале [1, anInteger].». Его реализация гласит
(self next * anInteger) truncated + 1
Итак, у меня есть два комментария:
В ST принято добавлять новые методы к существующим классам. Поэтому, если вы хотите, чтобы в Random было между: и:, просто добавьте его, например как
between: low and: high
^(self next * (high-low+1)) truncated + low
ну в том-то и дело. Мы вообще не используем Squeak. Версия, которую мы используем, имеет только next и nextValue.
Тем не менее, вы можете добавить любые новые методы, которые сочтете полезными.
Механизм, о котором говорит Мартин, называется расширениями классов. По сути, вы можете определить метод в классе, который был определен в другом месте, и при этом этот метод все еще будет упакован с остальной частью вашего кода, будь то файл или фиксация. Как это сделать, зависит от диалекта, но вы до сих пор не сказали нам, какой из них используете ...
Если вы используете VisualWorks, и: принимает блок в качестве аргумента, вы должны написать:
(aBoolean and: [anotherBoolean]) ifTrue: [doSomething].
Также есть &, который не принимает блок в качестве аргумента,
aBoolean & anotherBoolean ifTrue:[doSomething].
Разница в том, что и: оценивает только то, что находится в блоке, если первое bool истинно (аналогично java), тогда как & всегда оценивает и то, и другое.
Таким образом, and: пригодится, если второе условие требует больших вычислительных ресурсов или если оно включает изменения состояния, которые должны происходить только тогда, когда первое условие истинно. (хотя обычно это плохой дизайн).
Что касается Random, пока вы доставляете свой собственный метод, Random >> between: and:, а также остальную часть вашего кода, он отлично работает на компьютере вашего профессора. Как именно это сделать, зависит от формата, в котором вы должны выполнять задание.
(1 to: 1000) atRandom
Чтобы создать несколько случайных целых чисел от 1 до 1000
Сначала создайте серию случайных чисел. Сделайте это только один раз.
Затем создайте новое случайное число, взяв следующее число из ряда. При необходимости повторите.
aRandomSeries := Random new .
"Seed a new series of random numbers"
aRandomInt := aRandomSeries newInt: 1000 .
"generate a random integer between 0 and 1000"
anotherRandomInt := aRandomSeries newInt: 1000 .
"generate another random integer between 0 and 1000"
Логические операции
aBoolean ответит на and: и or:. Они оба берут блокировать аргументы.
Вот как они работают.
and: alternativeBlock
Если получатель - истина, ответьте на значение AlternativeBlock; в противном случае ответьте false без оценки AlternativeBlock.
or: alternativeBlock
Если получатель - ложь, ответьте значением optionBlock; в противном случае ответьте «истина» без оценки AlternativeBlock.
например, ( 3 > 2 ) or: [ 3 < 4 ] ifTrue: [ ]aBoolean and: [ anotherBoolean ] ifFalse: [ ]
Однако и Squeak, и Pharo Smalltalks принимают аргумент в круглых скобках ( )
.
Dolphin Smalltalk не будет и строго требует стандартного синтаксиса Smalltalk для аргумента блока.
Другие связанные методы:&И, который не требует аргумента в квадратных скобках (т. Е. Блочного)
|ИЛИ ЖЕ, который не требует аргумента в квадратных скобках (т. Е. Блочного)
& и | работают в Amber, Cuis, Gnu, Pharo, Squeak, VisualAge и VisualWorks Smalltalks.
Squeak Smalltalk также предоставляет: and:and: }and:and:and: } Принимают несколько аргументов блока.
and:and:and:and }
or:or: }or:or:or: } Принимают несколько аргументов блока.
or:or:or:or: }
Проще говоря, не зная диалекта Smalltalk, я могу дать только общий ответ. Как вы задали случайный вопрос, да, это единственный способ сделать это, если вашему профессору нужен общий ответ.
Что касается вопроса и / или утверждений,
And/Or statements. This one bugs the living daylights out of me. I have tried several different configurations of
(statement) and: (statement) ifTrue...
(statement) and (statement) ifTrue...
Что вы хотите попробовать:
(statement) and: [statement] ifTrue: [ ... ]
обратите внимание на скобки, метод and: принимает в качестве аргумента блок.
Было бы полезно разделить два разных вопроса на две отдельные страницы.