“死方法上下文"函数错误 [英] "Dead method context" error in a function

查看:76
本文介绍了“死方法上下文"函数错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个isBinary函数,该函数检查发送的行中是否有任何不可打印的字符(整数值在0-127范围之外):

I am trying to write a isBinary function that checks sent line if it has any non-printable characters (integer value outside range 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 ].

isBinary函数已到达,但它给出以下错误(文件是否为二进制文件):

isBinary function is reached but, it gives following error (whether the file is binary or not):

$ gst isbinary.st
"Global garbage collection... done"
/home/abcd/binaryfile.x : Reached isBinary fn.
Object: Character value: 16rC0 error: return from a dead method context
SystemExceptions.BadReturn(Exception)>>signal (ExcHandling.st:254)
SystemExceptions.BadReturn class(Exception class)>>signal (ExcHandling.st:151)
Character(Object)>>badReturnError (Object.st:1389)
String(SequenceableCollection)>>do: (SeqCollect.st:827)
[] in UndefinedObject>>executeStatements (isbinary.st:4)
optimized [] in UndefinedObject>>executeStatements (isbinary.st:16)
[] in Kernel.RecursiveFileWrapper(FilePath)>>filesMatching:do: (FilePath.st:903)
[] in Kernel.RecursiveFileWrapper>>namesDo:prefixLength: (VFS.st:378)
[] in File>>namesDo: (File.st:589)
BlockClosure>>ensure: (BlkClosure.st:268)
File>>namesDo: (File.st:586)
Kernel.RecursiveFileWrapper>>namesDo:prefixLength: (VFS.st:373)
[] in Kernel.RecursiveFileWrapper>>namesDo:prefixLength: (VFS.st:382)
[] in File>>namesDo: (File.st:589)
BlockClosure>>ensure: (BlkClosure.st:268)
File>>namesDo: (File.st:586)
Kernel.RecursiveFileWrapper>>namesDo:prefixLength: (VFS.st:373)
Kernel.RecursiveFileWrapper>>namesDo: (VFS.st:396)
Kernel.RecursiveFileWrapper(FilePath)>>filesMatching:do: (FilePath.st:902)
File(FilePath)>>allFilesMatching:do: (FilePath.st:775)
Directory class>>allFilesMatching:do: (Directory.st:225)
UndefinedObject>>executeStatements (isbinary.st:11)

在我的代码中用sline asArray do:替换sline do:也不起作用(相同的错误).

Replacing sline do: with sline asArray do: in my code also does not work (same error).

问题出在哪里,如何解决?感谢您的帮助.

Where is the problem and how can this be solved? Thanks for your help.

修改: 正如答案和评论中所建议的那样,我在类中使用method编写了以下代码,并且可以正常工作.我只是想请您发表评论,是否这是正确的方法.

As suggested in the answer and comments, I wrote following code with method in a class and this works. I just want your comments whether this is the right method.

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变量绑定到包含所谓的 non-local return 的块,该块无法以这种方式执行你打算原因是非本地返回的语义是从定义de block(它的词法上下文)的方法返回.如果这样的方法不存在或已经返回(换句话说,如果词法上下文不在调用堆栈中),则无法定义执行流应返回的位置.因此是错误.

Your isBinary variable is bound to a block that contains a so called non-local return, which cannot be executed the way you intend. The reason is that the semantics for a non-local return is to return from the method that defines de block (it's lexical context). If such a method does not exist or it already returned (in other words if the lexical context is not in the calling stack), there is no way to define where the execution flow should return. Hence the error.

要解决此问题,只需创建一个方法#isBinary:,该方法将使用您为该块编写的代码接收自变量sline.然后调用该方法,而不是评估该块.那会起作用的.

To solve this, just create a method #isBinary: that receives an argument sline with the code you wrote for the block. Then call the method instead of evaluating the block. That will work.

这篇关于“死方法上下文"函数错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆