Первые n символов строки или всей строки;без SubscriptOutOfBounds - PullRequest
0 голосов
/ 04 февраля 2019

В Pharo 7 я пытаюсь получить первое число символов строки или только всю строку (если запрошенное количество символов превышает длину строки).

Однакоследующий пример приводит к ошибке, тогда как я просто хочу, чтобы она возвращала всю строку:

    'abcdef' copyFrom: 1 to: 30. "=> SubscriptOutOfBounds Error"
    'abcdef' first: 30. "=> SubscriptOutOfBounds Error"
    'abcdef' first: 3. "=> 'abc'; OK"

Существует ли метод, который просто возвращает всю строку, если запрошенная длина превышает длину строки?

В качестве обходного пути я сделал следующее, чтобы сначала проверить длину строки и отправить first:, только если длина превышает максимальную длину, но это не очень элегантно:

label := aTaskbarItemMorph label size < 30 ifTrue: [ aTaskbarItemMorph label ] ifFalse: [ aTaskbarItemMorph label first: 30 ].

Ответы [ 4 ]

0 голосов
/ 05 февраля 2019

MethodFinder на помощь

Мы также должны помнить, что для таких случаев, как этот, у нас есть MethodFinder в Фаро.Вы используете его, оценивая имеющиеся у вас примеры.В нашем случае

MethodFinder methodFor: #(('abcdef' 30) 'abcdef' ('abcdef' 3) 'abc')

даст

"'(data1 contractTo: data2) (data1 truncateTo: data2) '"

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

'abcdef' contractTo: 6 "'a...f'"

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


Синтаксис

Синтаксис MethodFinder требует Array длины 2 * #examples, где каждый из примеров состоит из пары ( входные аргументы , результат ).

Интересно, что Squeak фигурные скобки позволяют легко создавать динамически создаваемые примеры:

input := 'abcdef'.
n := 1.
MethodFinder methodFor: {
     {input. input size + n}. input.
     {input. input size - n}. input allButLast
}

также найдет truncateTo:.

0 голосов
/ 04 февраля 2019

Вот простое выражение, которое принесет то, что вы хотите:

aString readStream next: n
0 голосов
/ 04 февраля 2019

Строка >> truncateTo:

'abcdef' truncateTo: 30. "'abcdef'"
'abcdef' truncateTo: 3. "'abc'"
0 голосов
/ 04 февраля 2019

Я не вижу такого метода по умолчанию в классе String или его суперклассах.Ваш обходной путь - хорошее решение.

В качестве альтернативы можно использовать min:, чтобы выбрать размер строки или ограниченное количество символов.Например:

string := '123456'.
label := string first: (string size min: 5).

Другое решение - добавить метод расширения в класс String, который делает то, что вы хотите.Таким образом, метод будет добавлен в класс String, но помещен в ваш пакет.Например:

String>>atMost: numberOfElement
    ^ self size < numberOfElement 
        ifTrue: [ self ] 
        ifFalse: [ self first: numberOfElement ]

Тогда будет работать следующее:

string := '123456'.
string atMost: 2.  "'12'"
string atMost: 10. "'123456'"

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

...