1

我正在尝试创建一个具有字符串修剪功能的类:

Object subclass: Trimmer [
    trimleading: str [ |ch ret|
        ch := (str first: 1).           "get first character"
        ret := str.                     "make a copy of sent string"
        [ch = ' '] whileTrue: [         "while first char is space"
            ret := (ret copyFrom: 2).   "copy from 2nd char"
            ch := ret first: 1.         "again test first char"
            ].
        ^ret                            "return value is modified string"
        ].
    trim: str [ |ret|
        ret := str. 
        ret := (trimleading value: ret).           "trim leading spaces"
        ret := (trimleading value: (ret reverse)). "reverse string and repeat trim leading"
        ^(ret reverse)                             "return reverse string"
        ]
].

oristr := '        this is a test  '
('ORI..>>',oristr,'<<') displayNl.
('FINAL>>',((Trimmer new) trim: oristr),'<<') displayNl.

但是,它没有运行并给出以下错误:

$ gst trimstring_class.st

trimstring_class.st:10: invalid class body element
trimstring_class.st:17: expected expression

问题出在哪里,如何解决?

如果我删除.after trimleading 方法块,如下面的代码:

Object subclass: Trimmer [
    trimleading: str [ |ch ret flag|
        ret := str.                     "make a copy of sent string"
        flag := true.
        [flag] whileTrue: [         "while first char is space"
            ch := ret first: 1.         "again test first char"
            ch = ' '
            ifTrue: [ ret := (ret copyFrom: 2 to: ret size)]    "copy from 2nd char"
            ifFalse: [flag := false] 
            ].
        ^ret                                "value is modified string"
        ]     "<<<<<<< PERIOD/DOT REMOVED FROM HERE."
    trim: str [ |ret|
        ret := str. 
        ret := (trimleading value: ret).           "trim leading spaces"
        ret := (trimleading value: (ret reverse)). "reverse string and repeat trim leading"
        ^(ret reverse)                      "return reverse string"
        ]
].

然后代码开始运行,但因以下错误而停止:

$ gst trimstring_class.st 
trimstring_class.st:15: undefined variable trimleading referenced
ORI..>>        this is a test  <<
Object: Trimmer new "<0x7f1c787b4750>" error: did not understand #trim:
MessageNotUnderstood(Exception)>>signal (ExcHandling.st:254)
Trimmer(Object)>>doesNotUnderstand: #trim: (SysExcept.st:1448)
UndefinedObject>>executeStatements (trimstring_class.st:23)

为什么trimleading方法现在是未定义的,为什么是 gnu-smalltalk did not understand #trim:

4

1 回答 1

2

通常,对于此类常见用例,检查此类功能是否已实现是明智之举。您可以从中获得灵感来编写您的代码(作为 Smalltalk 程序员,您也会有所进步)。看看trimBlanksFrom: from sports.st:

 SpStringUtilities class >> trimBlanksFrom: aString [
    "^a String
     I return a copy of aString with all leading and trailing blanks removed."

    <category: 'services'>
    | first last |
    first := 1.
    last := aString size.
    [last > 0 and: [(aString at: last) isSeparator]] 
        whileTrue: [last := last - 1].
    ^last == 0 
        ifTrue: [String new]
        ifFalse: [
            [first < last and: [(aString at: first) isSeparator]] 
                whileTrue: [first := first + 1].
            aString copyFrom: first to: last
       ]
]

如果您只想修剪前导空格,您可以只使用第二部分,它正在修剪前导空格。

编辑OP 自己的代码应用了修复:

Object subclass: Trimmer [
    trimleading: str [ |ch ret flag|
        ret := str.                     "make a copy of sent string"
        flag := true.
        [flag] whileTrue: [         "while first char is space"
            ch := ret first: 1.         "again test first char"
            ch = ' '
            ifTrue: [ ret := (ret copyFrom: 2 to: ret size) ]    "copy from 2nd char"
            ifFalse:  [flag := false ] 
            ].
        ^ret                                "value is modified string"
        ]     "<<<<<<< PERIOD/DOT REMOVED FROM HERE."
    trim: str [ |ret|
        ret := str. 
        ret := self trimleading: (ret copy).           "trim leading spaces"
        ret := self trimleading: (ret copy reverse). "reverse string and repeat trim leading"
        ^ (ret reverse)                      "return reverse string"
        ]
].

oristr := '        this is a test  '
('ORI..>>',oristr,'<<') displayNl.
('FINAL>>',((Trimmer new) trim: oristr),'<<') displayNl.

这是一些需要修复的错误。如果要处理选择器#trimleading:,则必须使用self搜索本地类的关键字(对于自己的类或继承的类)。接下来,您不应更改分配给您的变量,#copy否则可能会出现奇怪的结果。

于 2019-05-14T07:28:21.577 回答