首页 > 解决方案 > 如何在 Pharo 8 的 linux 终端下 stdin > Pharo program > stdout?

问题描述

我试图为此提供一个 Pharo 8 解决方案作为练习。这是一个简单的排序字数挑战。例如,一种 python 解决方案是:

import sys

counts = {}
for line in sys.stdin:
    words = line.lower().split()
    for word in words:
        counts[word] = counts.get(word, 0) + 1

pairs = sorted(counts.items(), key=lambda kv: kv[1], reverse=True)
for word, count in pairs:
    print(word, count)

sys 模块允许我们从终端通过管道传输文本,而不是从脚本内部手动打开文件,使用路径和文件名。

到目前为止,我能够通过从 Pharo 中加载文件来编写 Pharo 8 解决方案来应对这一挑战:

Object subclass: #WordCounter
    instanceVariableNames: 'contents sortedResults'
    classVariableNames: ''
    package: 'MyWordCounter'

WordCounter>>readFile: aPath
    "Takes a filepath and reads the contents of the file"
    
    | stream |      
    contents := OrderedCollection new.
    stream := aPath asFileReference readStream.
    [ stream atEnd ] whileFalse: [ contents add: stream nextLine asLowercase substrings ].
    stream close.

WordCounter>>rank
    "Counts the words and sorts the results"    
            
    | dict |
    dict := Dictionary new.
    contents do:
        [ :line | line do: 
            [ :word | dict at: word put: (dict at: word ifAbsent: 0) + 1 ] ].
    sortedResults := dict associations asSortedCollection: [ :a1 :a2 | a1 value > a2 value ]

WordCounter>>show
    "Print the sorted results to transcript"
    Transcript clear.
    sortedResults do: [ :each | Transcript show: each key; show: ' '; show: each value; cr ]

定义了这个类后,现在我可以通过在操场上执行以下代码来获得结果:

| obj |
obj := WordCounter new.
obj readFile: '/home/user/WordCounterPharo/kjvbible_x10.txt'.
obj rank; show.

我认为我的算法工作正常,如下所示:

在此处输入图像描述

现在的问题是,我想修改这个程序,这样,在 Linux 中,它只是从管道中摄取数据并将结果打印回终端,而不是使用文件路径读取数据并将结果写入脚本. 我知道 Pharo 具有命令行功能,当我下载 Pharo 时出现的第一个示例是在终端中运行它:

./pharo Pharo.image eval "42 factorial"

所以我想要的最终结果是这样的模拟输出:

user@PC:~$ ./pharo Pharo.image WordCounter < kjvbible_x10.txt
user@PC:~$ the 640150
user@PC:~$ and 513130
user@PC:~$ of 346340
user@PC:~$ to 135670
user@PC:~$ that 127840
user@PC:~$ in 125030
user@PC:~$ he 102610
user@PC:~$ shall 98380
user@PC:~$ unto 89870
user@PC:~$ for 88100
user@PC:~$ i 87080
user@PC:~$ his 84500
user@PC:~$ a 81760
user@PC:~$ they 72970
user@PC:~$ be 68540
...

但我仍然无法弄清楚自己该怎么做。我试图通过@tukan 遵循这个答案,但我怀疑从那时起使用的类 OSProcess 已被删除,因为 Pharo 8 无法识别它(在操场上涂成红色,检查时返回未知变量错误)。我还注意到在 Windows 下有一个关于 pharo的类似问题,但没有得到解答。

奖励问题:在写这篇文章时,我注意到在这里共享代码,我必须逐个方法地复制和粘贴代码。如果它是一个大类(幸运的是我的只有 3 个方法),那可能会有点麻烦。有没有更简单的方法,一次完成?

标签: textstdoutstdinsmalltalkpharo

解决方案


推荐阅读