Smalltalk输入/输出

时间:2015-04-12 00:37:44

标签: smalltalk

我在使用Smalltalk方面遇到了麻烦。我试图用从文件中读取的数字填充数组,但它似乎不起作用。我尝试了很多选择,我希望有人能向我解释我做错了什么。

 Object subclass: #MyStack
        instanceVariableNames:'anArray aStack'
        classVariableNames:''
        poolDictionaries:''

!
MyStack class comment: 'Creates a Stack Class.'
!

!
MyStack methodsFor: 'initialize Stack'
!

new "instance creation"
        ^ super new.
!
init "initialization"
        anArray := Array new: 32.
        aStack := 0.
! !

!MyStack methodsFor: 'methods for stacks' !


pop "Removes the top entry from the stack"
    | item |
    item := anArray at: aStack.
    aStack := aStack - 1.
!

push: x "Pushes a new entry onto the stack"
    aStack := aStack + 1.
    anArray at:aStack put:x.
!

top "Returns the current top of the stack"
        ^anArray at: aStack.
!

empty "True if the stack is empty"
        ^aStack = 0.
!

full "True if the stack is full"
        ^aStack = 32.
!

printOn: aStream "Prints entire stack one entry per line, starting the top entry"
    aStream show: 'Stack:'.
    aStack to:1 by:-1 do:[:i |(anArray at:i) printOn:aStream. ].
    aStream show: ''
! !
"----------------------------------------------------------------------------------"
Object subclass: #IOExample
  instanceVariableNames: 'input output'
  classVariableNames: ''
  poolDictionaries: ''
!
IOExample class comment: '
 basic I/O.
'
!

!
IOExample methodsFor: 'initialize'
!
new
  ^ super new.

!
init
  [ input := FileSelectionBrowser open asFilename readStream. ]
    on: Error
    do: [ :exception |
      Dialog warn: 'Unable to open file'.
      exception retry.
    ].
  [ output := FileSelectionBrowser open asFilename writeStream. ]
    on: Error
    do: [ :exception |
      Dialog warn: 'Unable to open file'.
      exception retry.
    ].

! !

!
IOExample methodsFor: 'copy input to output turning :: into :'
!
copy
  | data lookAhead theStack myStack|
  [ input atEnd ] whileFalse: [

    data := input next.
    (data isKindOf: Integer)
      ifTrue: [
        (input atEnd) ifFalse: [
        "myStack push: data."
        lookAhead = input peek.
        (lookAhead asCharacter isDigit)
            ifTrue: [
            ]              
        ].
      ].  
    output show: myStack.



  ].
  input close.
  output close.
! !

2 个答案:

答案 0 :(得分:3)

您是否尝试过运行此代码?如果你这样做,我很惊讶你没有收到由于#2下面的编译警告。

#copy中存在许多问题(除了我不明白它究竟在做什么之外)...

  1. 首先,您似乎希望数据为数字:data isKindOf: Integer。但后来你把它视为一个角色流:lookAhead asCharacter isDigit。如果第一个条件为真,让你越过那个点,第二个条件永远不会,因为你将匹配[0-9],这不是数字的ASCII值。
  2. lookAhead = input peek。在这里,您将未初始化的lookAheadnil)与偷看的值进行比较,然后丢弃结果。我认为你的意思是lookAhead := input peek
  3. 然后是空的内在条件ifTrue: [ ]。你想在那里做什么?
  4. 然后是奇怪的协议名称,'复制输入到输出转动::进入:'。这是什么意思,这与在流之间复制数字有什么关系呢?

答案 1 :(得分:2)

Justin,让我试着帮助你完成课程MyStack,并根据你的例子推荐另一个答案。

我已将您的代码分成片段并附加我的评论。


片段A:

Object subclass: #MyStack
    instanceVariableNames:'anArray aStack'
    classVariableNames:''
    poolDictionaries:''

A的评论:

Smalltalker会使用没有不确定文章aan

的实例变量名称
Object subclass: #MyStack
    instanceVariableNames:'array stack'
    classVariableNames:''
    poolDictionaries:''

片段B:

MyStack class comment: 'Creates a Stack Class.'

B的评论:

这很奇怪。我原本期望这样做(没有class):

MyStack comment: 'Creates a Stack Class.'

片段C:

MyStack methodsFor: 'initialize Stack'

new "instance creation"
    ^ super new.

C:*

的评论

此代码将new放在类的实例端,这没有任何意义,因为您通常会将new发送给类而不是其实例。正确的表单需要添加class

MyStack class methodsFor: 'initialize Stack'

new
    ^super new.

您忘记发送初始化方法(但请参阅下面的片段D)

new
    ^super new init.

片段D:

init "initialization"
    anArray := Array new: 32.
    aStack := 0.

D的评论:

在Smalltalk中,人们使用选择器initialize,因此它可以发送超级优先

initialize
    super initialize.
    array := Array new: 32.
    stack := 0.

请注意,此更改还需要将new写为

new
    ^super new initialize.

但是,如果您的方言默认情况下已发送initialize方法,则应从您的班级中移除new的实施。


片段E:

pop "Removes the top entry from the stack"
    | item |
    item := anArray at: aStack.
    aStack := aStack - 1.

E的评论:

您忘了回答刚刚弹出的item

pop
    | item |
    item := array at: stack.
    stack := stack - 1.
    ^item

片段F:

push: x "Pushes a new entry onto the stack"
    aStack := aStack + 1.
    anArray at:aStack put:x.

对F的评论:

这没关系。但请注意,堆栈将拒绝超出32的限制推送任何项目。

push: x
    stack := stack + 1.
    array at: stack put: x.

片段G:

top "Returns the current top of the stack"
    ^anArray at: aStack.

empty "True if the stack is empty"
    ^aStack = 0.

full "True if the stack is full"
    ^aStack = 32.

G的评论:

这些也可以。但是,empty的更合适的名称可能是isEmpty,因为所有集合都理解这种多态消息。同样,full的推荐选择器为isFull

top
    ^array at: aStack.

isEmpty
    ^stack = 0.

isFull
    ^stack = 32.

另请注意,isFull重复您在初始化代码中使用的魔术常量32。这不是一个好主意,因为如果你将来改变主意并决定用64改变32,你将不得不修改两种方法而不仅仅是一种方法。你可以用这种方式消除这种重复

isFull
    ^stack = array size.

片段H:

printOn: aStream
    "Prints entire stack one entry per line, starting the top entry"
    aStream show: 'Stack:'.
    aStack to:1 by:-1 do:[:i |(anArray at:i) printOn:aStream. ].
    aStream show: ''

对H的评论:

这段代码的最后一行是多余的,我会摆脱它。但是,您可能希望使用空格

分隔下一个项目
printOn: aStream
    stream show: 'Stack:'.
    stack to: 1 by: -1 do:[:i |
        aStream space.
        (array at: i) printOn: aStream].