Function 函数中的“死方法上下文”错误

Function 函数中的“死方法上下文”错误,function,smalltalk,Function,Smalltalk,我正在尝试编写一个isBinary函数,用于检查发送行是否有任何不可打印字符整数值超出范围0-127: isBinary := [ :sline | 'Reached isBinary fn.' displayNl. sline do: [ :char | "for each character" i := char asInteger. "convert to integer" (i < 0 | i >

我正在尝试编写一个isBinary函数,用于检查发送行是否有任何不可打印字符整数值超出范围0-127:

isBinary := [ :sline |
    'Reached isBinary fn.' displayNl.
    sline do: [ :char |           "for each character"
        i := char asInteger.      "convert to integer"
        (i < 0 | i > 127) 
        ifTrue: [^true]. ].       "return true if found unprintable"
    ^false. ].                    "if not found above, return false"

(Directory working: '.') allFilesMatching: '*.x'
do: [ :ff |
    ((ff name), ' : ') display.
    infile := FileStream open: ff name mode: FileStream read.
        firstline := infile nextLine.
        (isBinary value: firstline) 
        ifTrue: ['Binary file' displayNl.]
        ifFalse: [ 'Not a binary file' displayNl].
    infile close ].
在我的代码中将sline-do:替换为sline-asArray-do:也不会出现相同的错误

问题在哪里?如何解决?谢谢你的帮助

编辑: 正如回答和评论中所建议的,我在一个类中用方法编写了以下代码,这很有效。我只想听听你的意见,这是否是正确的方法

Object subclass: Checker [ 
    isBinary: sline [ 
        'Reached isBinary fn.' displayNl.
        sline do: [ :char |  | i |           "for each character"
            i := char asInteger.             "convert to integer"
            i > 127
            ifTrue: [^true]     "return true if found unprintable"  
        ].       
    ^false. ]      "if no unprintable char found, return false"
].

(Directory working: '.') allFilesMatching: '*.x'
do: [ :ff |
    '------------------------------' displayNl.
    ((ff name), ' : ') displayNl.
    infile := FileStream open: ff name mode: FileStream read.
        firstline := infile nextLine.
        ((Checker new) isBinary: firstline)
        ifTrue: ['Binary file' displayNl.]
        ifFalse: [ 'Not a binary file' displayNl].
    infile close ].
isBinary变量绑定到一个包含所谓非局部返回的块,该块不能按您想要的方式执行。原因是非局部返回的语义是从定义其词法上下文的方法返回。如果这样一个方法不存在,或者它已经返回,换句话说,如果词法上下文不在调用堆栈中,则无法定义执行流应该返回的位置。因此出现了错误


要解决这个问题,只需创建一个方法isBinary:它接收一个参数sline,其中包含您为该块编写的代码。然后调用该方法,而不是计算块。这将起作用。

下面的独立方法/块代码通过创建一个返回变量来工作,如果找到不可打印的字符,该返回变量的值将在循环中操作。然后退出循环:

isBinary := [ :sline |            "WORKS"
    'Reached isBinary fn: ' display.
    ret := false.                 "return variable initialized to false"
    sline do: [ :char |           "loop for each character in sent line"
        i := char asInteger.      "convert to integer"
        i > 127                   "check if printable"
        ifTrue: [ret := true. exit]].   "ret becomes true if found unprintable; does not work if ^ symbol is used"  
    ret].            "if not found above, ret remains false; ret is returned value"

以上操作不需要按照OP me!的要求创建类

如何创建isBinary?把我的函数重命名为这个名字?或者我需要用这个方法创建一个单独的类吗?我想避免创建一个新类。非常感谢您的代码示例。您可以编写sline allsuccess:[:char | char asInteger>127]并避免出现问题,因为您将有一个干净的块,而不引用外部context@aka.nice实际上,anysuccess工作得很好:sline anysuccess:[:char | char asInteger>127]。谢谢。@RN所以对于你的另一个问题,这个答案确实和我的差不多。这里增加的困难是,您想要从isBinary的循环中中断。如果没有合适的返回方法,这是不容易实现的。AnySemit是一个正确的方法,它将从循环中返回非局部返回,就像在原始代码中一样。@rnso Leandro建议您为isBinary创建一个正确的方法,然后使用一个参数,从而添加冒号。我同意他的观点,而且,由于到目前为止您似乎只从命令行运行过简单的脚本,因此建议您学习如何在GNU Smalltalk中创建类和方法,而不是仅仅运行简单的脚本,这些脚本本质上是一个单一的方法。如果你已经知道怎么做了,你不应该为了简洁而回避它。
isBinary := [ :sline |            "WORKS"
    'Reached isBinary fn: ' display.
    ret := false.                 "return variable initialized to false"
    sline do: [ :char |           "loop for each character in sent line"
        i := char asInteger.      "convert to integer"
        i > 127                   "check if printable"
        ifTrue: [ret := true. exit]].   "ret becomes true if found unprintable; does not work if ^ symbol is used"  
    ret].            "if not found above, ret remains false; ret is returned value"