"Dead method context" 函数错误
"Dead method context" error in a function
我正在尝试编写一个 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 ].
isBinary
功能已达到,但出现以下错误(无论文件是否为二进制文件):
$ 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:
也不起作用(同样的错误)。
问题出在哪里,如何解决?感谢您的帮助。
编辑:
正如答案和评论中所建议的那样,我在 class 中使用方法编写了以下代码并且可以正常工作。我只想要您的意见,这是否是正确的方法。
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 的块,该块无法按照您的方式执行打算。原因是 non-local return 的语义是 return 来自定义 de block 的方法(它是词法上下文)。如果这样的方法不存在或已经 returned(换句话说,如果词法上下文不在调用堆栈中),则无法定义执行流应该 return 的位置。因此错误。
要解决这个问题,只需创建一个方法 #isBinary:
接收一个参数 sline
以及您为该块编写的代码。然后调用方法而不是评估块。那行得通。
以下独立 method/block 代码通过创建一个 return 变量来工作,如果发现不可打印的字符,该变量的值将在循环中进行操作。然后退出循环:
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(我!)的要求创建 class。
我正在尝试编写一个 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 ].
isBinary
功能已达到,但出现以下错误(无论文件是否为二进制文件):
$ 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:
也不起作用(同样的错误)。
问题出在哪里,如何解决?感谢您的帮助。
编辑: 正如答案和评论中所建议的那样,我在 class 中使用方法编写了以下代码并且可以正常工作。我只想要您的意见,这是否是正确的方法。
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 的块,该块无法按照您的方式执行打算。原因是 non-local return 的语义是 return 来自定义 de block 的方法(它是词法上下文)。如果这样的方法不存在或已经 returned(换句话说,如果词法上下文不在调用堆栈中),则无法定义执行流应该 return 的位置。因此错误。
要解决这个问题,只需创建一个方法 #isBinary:
接收一个参数 sline
以及您为该块编写的代码。然后调用方法而不是评估块。那行得通。
以下独立 method/block 代码通过创建一个 return 变量来工作,如果发现不可打印的字符,该变量的值将在循环中进行操作。然后退出循环:
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(我!)的要求创建 class。