2009-10-29 9 views
8

Smalltalkで2つの文字列を比較しようとしていますが、何か間違っているようです。Smalltalk - 2つの文字列を等価で比較する

私はこのエラーを取得しておいてください。

未処理の例外:非ブール受信機。真実を続ける。

stringOne := 'hello'. 
stringTwo := 'hello'. 
myNumber := 10. 

[stringOne = stringTwo ] ifTrue:[ 
    myNumber := 20]. 

私は間違っていると思いますか?

答えて

16

は、私はあなたが偉大な説明最初に見つかった行

で角括弧を必要としないと思う

stringOne = stringTwo 
    ifTrue: [myNumber := 20]` 

を試してみてください。全体はthing is here

スモールトークでは、ブール値(つまり、真または偽)はオブジェクトです。具体的には、抽象基底クラスブールのインスタンス化、またはその2つのサブクラスのTrueおよびFalseのインスタンス化です。したがって、すべてのブール値はTrueまたはFalseの型を持ち、実際のメンバーデータはありません。 Boolには、ifTrue:とifFalse:の2つの仮想関数があり、それらは引数として1ブロックのコードを取ります。 TrueとFalseの両方がこれらの関数をオーバーライドします。 TrueのifTrueバージョン:渡されたコードを呼び出し、Falseのバージョンは何もしません(逆もまた同様です)。ここに例があります:

a < b 
    ifTrue: [^'a is less than b'] 
    ifFalse: [^'a is greater than or equal to b'] 

大括弧で囲まれたものは、基本的に匿名関数です。オブジェクトはスモールトークのオブジェクトなので、それらはオブジェクトです。さて、ここで起こっているのは、引数 "b"を使って "<"メソッドを呼び出すことです。これはブール値を返します。 ifTrue:とifFalse:メソッドを呼び出し、どちらの場合でも実行したいコードを引数として渡します。その効果はRubyコードと同じです

if a < b then 
    puts "a is less than b" 
else 
    puts "a is greater than or equal to b" 
end 
+0

おかげで私の仲間のアンドロイド。それが問題でした。 – user69514

+0

Woof - 私はそれほどよく知られていませんw Smalltalkだが、角括弧は評価のためのものであり、 '= '演算子を評価するとブール値は得られません:) – Bostone

+0

sigh - ここでacodeの例を追加したいそれは書式が間違っていた。それを忘れて、私は答えを追加しました... – blabla999

0

比較をブロックしてください。私はそれを考えていたでしょう:

(stringOne = stringTwo) ifTrue: [ myNumber := 20 ] 

で十分でしょう。

+1

括弧は不要で非典型的です。実際、括弧(特にネストされた括弧)を必要とする式を書くと、おそらく複雑すぎることになり、名前付きの一時呼び出しや別のメソッド呼び出しにリファクタリングする可能性があります。 –

1

[stringOne = stringTwo]はブール値ではなくブロックです。ブロックが呼び出されると、おそらくブール値になります。しかし、あなたはここでブロックを呼び出すことはありません。代わりに、ブロックをifTrueの受信者にするだけです。

代わりに、試してみてください。他の人が言ったように

(stringOne = stringTwo) ifTrue: [ 
    myNumber := 20 ]. 
4

、それはあなたが角括弧の最初のセットを取り除く場合はあなたが望むように動作します。

しかし、あなたがより良いに実行していた問題を説明する:

[stringOne = stringTwo ] ifTrue:[myNumber := 20] 

がブロックにメッセージifTrue:を通過している、とブロックはその方法を理解していない、唯一のブーリアンオブジェクトが行います。

あなたが最初のブロックを評価した場合、それがtrueの場合、対応する方法を知っているオブジェクト、と評価されます:

[stringOne = stringTwo] value ifTrue:[myNumber := 20] 

または何他の人が指摘したように、あなたが本当に、実行する必要があります。

stringOne = stringTwo ifTrue:[myNumber := 20] 

を送信する前に、stringOne = stringTwo~trueの両方を評価します。

0

but I seem to be doing something wrong

あなたはにドキュメントフォルダを含める必要がありますインストールし、あなたのVisualWorksを使用していることを考えます。

AppDevGuide.pdfを参照してください。VisualWorksでのプログラミングに関する多くの情報があります。さらに、Smalltalkプログラミングに関する入門的な情報がたくさんあります。

第7章制御構造まで、目次の表を見て、「ブランチング」または「条件付きテスト」をクリックすると、pdfの該当セクションに移動しますスモールトークif-then-elseとあなたが間違っていたことを見るのに役立つはずの例を挙げています。私は、次の50Cent追加したい

0

do:aBlock ifCondition:aCondition 
    ... some more code ... 
    aCondition value ifTrue: aBlock. 
    ... some more code ... 
    aBlock value 
    ... 

のでifTrueへの引数:ブロックは実際に周りに渡すことができるラムダあるとして、別の良い例を

以下の方法は、次のようになります。/ifFalse:実際には他の誰かから来ることができます。このような渡された条件は、 "..ifAbsent:"や "..onError:"のような種類のメソッドで役に立ちます。

(元々はコメントとして意味が、私は未フォーマットするコード例を取得できませんでした)

関連する問題