1

行列(y行、x列)にスペースを割り当てるメソッドdim(x、y)を実装したいと思います。

オプションの関数「filler」を渡すことで「dim(x、y)」をより強力にしたいのですが、「dim」は(x、y)にある要素をfiller(x、y)に設定します

私のコードは次のようになります:

List2D dim := method(x, y, z,
    target := list()
    filler := if(z == nil, 
        method(return nil),
        z)
    for(i, 1, y, 
        subTarget := list()
        for(j, 1, x,
            subTarget append( filler(i,j) ))
            target append(subTarget) )
    return target)

'dim'が2つの引数で呼び出された場合はうまく機能しましたが、

List2D dim(3,2, method(x,y, 10*x+y))

行で例外をスローしました例外はfiller := if(z == nil 言ったnil does not respond to '*'

nilと比較すると、引数「z」が望ましくない形でアクティブになっていることに気付きました。

だから私は私の「List2Ddim」を正しく動作させる方法を考えていますか?

4

1 に答える 1

6

さて、基本的に、あなたはこのようなものが欲しいでしょう:

List2D dim := method(x, y,
    target := list
    blk := call evalArgAt(2) # Get the third argument, and evaluate it in the context of the sender
    if(blk isNil, blk := block setScope(call sender))

    for(i, 1, y,
        subTarget := list
        for(j, 1, x,
            subTarget append(blk call(i, j))
            target append(subTarget)
        )
    )
    target
)

基本的に、ここで行われているのは、フィラーが引数を指定するためです。最も簡単な方法は、を渡すだけBlockです。Blockこれはメッセージで行うことができますが、実際には、新しいスコープを導入した場合は、とにかく独自の複製を設定することになります。3番目の引数が次のように評価される場合nil次に、新しい関数を作成し、そのスコープを呼び出し元のコンテキストに設定します。ユーザーが引数を持たない空の関数を渡したかのように、そのため、パラメーターが定義されていない場合でも、引数を渡すことができます。呼び出し元にスコープを設定するという事実は実際には必要ありませんが、メソッド呼び出し内にブロックを作成する場合は、常に呼び出し元のコンテキストにブロックをスコープする必要があります。これにより、そのブロック内の呼び出しコンテキストの字句スコープにアクセスできるようになります。これはおそらく、ユーザーが入力したメッセージを表示していると思われます。準備ができたら、メソッドを使用してそのメソッドを明示的に呼び出しますcall

メソッドが引数を必要としない場合fillerは、評価するのではなく、2番目のインデックスで生のメッセージ引数を取得します。これにより、いくつかの大きなマトリックスのパフォーマンスが大幅に向上します。

于 2013-01-13T15:51:06.607 に答える