0

従来のClassicASPアプリケーションにある程度の健全性を持たせようとしています。その一環として、作成したいくつかのJScriptクラス用にFluentAPIを作成しようとしています。

例えばmyClass().doSomething().doSomethingElse()

概念はここに概説されています(VBScriptで)

これは私のサンプルJScriptクラスです。

var myClass = function () {
    this.value = '';
}

myClass.prototype = function () {

    var doSomething = function (a) {
        this.value += a;
        return this;
    },

    doSomethingElse = function (a, b) {
        this.value += (a + b);
        return this;
    },

    print = function () {
        Response.Write('Result is: ' + this.value + "<br/>");
    }

    return {
        doSomething: doSomething,
        doSomethingElse: doSomethingElse,
        print: print
    };

}();

/// Wrapper for VBScript consumption
function MyClass() {
    return new myClass();
}

次に、既存のVBScriptコードで、メソッドをチェーン化しようとしています。

dim o : set o = MyClass()
'' This works
o.doSomething("a")

'' This doesn't work
o.doSomething("b").doSomethingElse("c", "d")

'' This for some reason works
o.doSomething("e").doSomethingElse("f", "g").print()

関数に複数のパラメーターがある場合、" Cannot use parentheses when calling a Sub"VBScriptエラーが発生します。不思議なことに、別の方法を実行すると機能するようです。

潜水艦を呼び出すときは括弧を省略すべきだと理解しています。でも:

1.戻り値があるのに、なぜSubとして認識されるのですか?

2. Fluent APIを実装するためにこれを回避する方法はありますか?

4

3 に答える 3

5

ルールは次のとおりです。「名前付きコード」を sub として呼び出すときは、param list () は使用しないでください。厄介なトラップは次のとおりです。単一パラメーター npcs の場合、() は param list () のように見えるかもしれませんが、(解釈される) pass-me-by-value () です。

my MyClass set o = MyClass()() を関数として呼び出します。それは課題から明らかです。

サブとして.doSomethingo.doSomething("a")を呼び出すと、() は pass-me-per-value (); と見なされます。doSomething "a"が正しい呼び出しになります。

o.doSomething("b").doSomethingElse("c", "d")あなたの作品の最初の部分はo.doSomething("b").、関数呼び出しを使用して、呼び出されるオブジェクトを取得するため.doSomethingElse()です。2 番目の部分.doSomethingElse("c", "d")は、サブ呼び出しではなく (戻り値が使用/割り当てられていない) () が pass-me-by-value () と見なされないため、機能しません。o.doSomething("b").doSomethingElse "c", "d"正しいでしょう。

最初の部分o.doSomething("e").doSomethingElse("f", "g").print()(.print まで) は関数呼び出し (.print するオブジェクトを取得するため) であるため、() は param list (); です。.print の後の () は間違っていますが、コンパイラー/インタープリターはそれらをすり抜けさせました。

要約すると、何かを返したくない場合は () を使用しないでください。

WRT コメント:

逆に言えば、何かを返したいときは () を使います!

set o1 = MyClass()<- 戻り値は o1 に入る必要があります

set o2 = o.S(1, 2).S(3, 4).S(5, 6)<- 最初の 2 つの戻り値が必要であり、次の呼び出しに使用されます。最後の戻り値は o2 に入ります。

o.S(1, 2).S(3, 4).S 5, 6<- 最後の戻り値は破棄されます - サブコールはありません

() ルールは、npc が何であるかではなく、何をするか (戻り値を使用するかどうか) に関するものです

于 2013-01-09T16:44:01.270 に答える
3

You can put call at the start of each line of vbscript. This will accept brackets being put on each method call, e.g.

' This works
call o.doSomething("b").doSomethingElse("c", "d")

' This works too
call o.doSomething("e").doSomethingElse("f", "g").print()

Or just don't put the parantheses in the vbscript when it complains...

See Differences between VBScript and JavaScript

于 2013-01-09T16:26:28.773 に答える
2

ちなみに、VBScriptで流暢なAPIを書くことができます。「タグスープ」のゴミを避けるためにHTMLのインライン作成を容易にするライブラリを構築し、現在アプリで使用しています(この質問を見つけた方法です)。

960gsグリッドをラップする2つのヘルパーの例を次に示します。

with html
  .open
    with head
      .open
        stylesheet_link "assets/stylesheets/960gs/reset.css"
        stylesheet_link "assets/stylesheets/960gs/960.css"
        stylesheet_link "assets/stylesheets/960gs/text.css"
        stylesheet_link "assets/stylesheets/app.css"
      .close
    end with
    with body
      .open
        with grid_container(12)
          .open
            call main
          .close
        end with
      .close
    end with
  .close
end with

そして、mainはこれに似ている可能性があります:

with grid_row
  with grid_column(4)
    .id "nav-left"
    .open
      with ul
        .open
          li.open.contains( link_to("Google", "http://google.com") ).close
          li.open.contains( link_to_if(a > b, "Microsoft", "http://microsoft.com") ).close
          li.open.contains( link_to_unless(a > b, "Apple", "http://apple.com") ).close
        .close
      end with
    .close
  end with
  with grid_column("8 push_2")
    .id "main-content"
    .open
      h1.open.contains("Title Here").close
      do until recordset.eof
        p.class("record").open.contains(recordset("column_name")).close
        recordset.movenext
      loop
    .close
  end with
end with

libの記述方法は、基本的にゼロの労力でXMLを生成できます。基本的には、「属性を持つネストされた要素」構造を持つ任意のタグ言語です。

クラシックASPは、それを使用する人々とチュートリアルを作成した人々がそれを捨てて、言語とグッドプラクティスを完全に理解していなかったため、そのように見えます。そのため、曲がりくねったコードの嘔吐を維持することに固執しています。しかし、それを正しく行うと、ルビーのように見え始める可能性があります。数年前に動的vbscriptクラスを使用していくつかのルビー反復を実装し、それが実行可能かどうかを確認しましたが、かなり前にそのコードを失いました。ポイントは、vbscriptは制限されていますが、それでも人々がそれを信用するよりも多くの機能を持っているということです。

于 2013-02-13T17:29:36.793 に答える