問題タブ [lexical-scope]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
scheme - let/set で値を「記憶」するスキーム関数
私はSchemeが初めてで、関数内に表示される特定の値が複数の用途でどのように保持されるかを理解しようとしています。次のカウンターを取ります。
私が理解できない (そしてどこにも説明されていない) のは、使用さnext
れるたびに が 0 にリセットされない理由count
です。
perl - Perl の字句スコープのプラグマはどのように実装されていますか?
autodie
ドキュメントによると、のようなプラグマはレキシカルスコープです。
これは、ロードされたすべてのモジュールに適用されますuse
か? 私の知る限り、次use
のものとほぼ同じです。
BEGIN
コンパイル時に発生し、require はレキシカル スコープではありません。では、その範囲をどのようにautodie
認識していますか?
emacs - emacsの字句スコープと引用符で囲まれた変数名
私はEmacsの字句スコープ(Emacs 24の新機能)間の相互作用を実験してadd-to-list
いて、相互作用が混乱していることに気づき、それを理解する方法がわかりません。set
の代わりに使用することを除いて、これは最小限の例ですadd-to-list
。(通常、引用符で囲まれた変数名を使用するという点でset
似ています)add-to-list
上記のコードは、「mature apple」、「mature apple」、「byset」を順番に出力します。最初の印刷結果である「成熟したリンゴ」は、字句スコープ(字句クロージャをサポート)で期待どおりであり、ここで驚くことはありません。しかし、2番目と3番目の印刷の結果は私には驚くべきものです。これ(set 'a "by set")
は、名前のグローバルバインディングを認識して影響を与えるだけであるかのようですa
。
これは意図された動作ですか?それともこれはバグですか?意図されている場合、この動作をどのように理解しますか?
set
字句スコープがオンになっている限り、影響を与えるのは常にグローバルバインディングであると想定するのは正しいですか?
を使用(eval '(progn ...) nil)
すると、動的スコープで期待どおりに動作し、の動作はその場合(set 'a ...)
と同じになり(setq a ...)
ます。字句スコープと引用符で囲まれた変数を一緒に使用する場合にのみ、この落とし穴が表示されます。
アップデート:
マニュアルによると、意図した動作のようです。ボイド変数については、マニュアルによると
字句バインディングルールでは、値セルは変数のグローバル値、つまり字句バインディング構造の外側の値のみを保持します。変数が字句的にバインドされている場合、ローカル値は字句環境によって決定されます。シンボルの値セルが割り当てられていない場合、変数はローカル値を持つ可能性があります。
symbol-value、boundp、setなどの関数は、変数の動的バインディング(つまり、シンボルの値セルの内容)のみを取得または変更します。
symbol-value、boundp、setは、通常、引用符で囲まれた変数名((symbol-value 'var) (boundp 'var) (set 'var 123)
)で呼び出される関数です。これらの関数は、シンボルの値セルのみを取得または設定し、字句バインディングルールでは、値セルはグローバル値のみを保持します。したがって、字句バインディングでは、引用符で囲まれた変数を使用すると、グローバル値のみが取得または設定されます(変数が特別な変数でない場合)。結果が字句(リンゴ)でも動的(バナナ)でもないという点でまだ奇妙に思えますが。
emacs - Emacs: defun または defmacro の本体内のコードは、周囲のレキシカル変数を参照できませんか?
2013 年 5 月の更新: GNU Emacs 24.3.1 の時点で、(let .. (defun..)) は警告なしで問題なくバイトコンパイルされ、バイトコンパイルされたコードはコンパイルされていないコードと同じように機能します。バイトコンパイルするファイルにfile 変数を追加することを忘れないでくださいlexical-binding: t
。この質問の最後にある回避策は不要になりました。
レキシカル バインディング - Emacs Lisp マニュアルには次の段落があります。
symbol-value、boundp、set などの関数は、変数の動的バインディング (つまり、そのシンボルの値セルの内容) のみを取得または変更することに注意してください。また、defun または defmacro の本体のコードは、周囲のレキシカル変数を参照できません。
2 番目の文の意味を正しく理解しているかどうかはわかりません。レキシカル バインディング モードで実行する必要がある次のコードでは、defun の本体のコードが name のレキシカル バインディング値を正常に参照していますn
。
(let .. (defun ..)) は悪い習慣だと言っているだけですか?
回避策:
上記のコードをテストするためのコードは次のとおりです。
r - `getClasses()` のデフォルト環境のあいまいなバリエーション (標準関数と正式な S4 メソッド)
「環境の入れ子」/字句スコープに関して、ここで正確に何が起こっているのかを理解するのに苦労しています:
問題
where
関数内の引数のデフォルト値は、標準の R 関数内で呼び出されるか、正式な S4 メソッドgetClasses()
内で呼び出されるかによって異なるようです。遅延評価の「オブジェクト」と思われるものによって制御されるため、バリエーションが発生します(以下の編集を参照)getClasses()
.externalCallerEnv()
質問
正式な S4 メソッド内から呼び出された場合、標準関数内で呼び出されたwhere
ときのデフォルト値と同じ値に設定するにはどうすればよいですか?getClasses()
図
以下に、上記の「問題のある動作」の簡単な図を示します。
1) カスタムクラス
現在ソースになっているクラス定義が多数あり.GlobalEnv
ます。
これをすべての代表として取り上げましょう
2) 利用可能なクラスの一覧表示
where
関数は引数を介しgetClasses
て、クラスを探す環境を選択させてくれます。
以下は、例外を除いてどこにでもあるように見える.GlobalEnv
ため、私のクラスが見つかりません。それはいいです:
今、私.GlobalEnv
はクラスA
だけを調べて見つけました。それもいいです:
3) カスタム標準ルックアップ関数の作成
標準関数(これは必要な機能の最初の部分にすぎず、戻り値を正式な引数として渡すのではなく、そのメソッド内で計算したい) にルックアップ ビアを配置するgetClasses
と、すべて正常に動作します。getClasses()
4) 正式な S4 メソッドの作成
ただし、すべてを正式なS4メソッドgetClasses()
に入れると、クラスを探すために使用する標準環境に関していくつかの変更があるようです
以前"A" %in% foo1(where=NULL)
はFALSE
(望ましい)でした"A" %in% foo2(where=NULL)
が、TRUE
現在は ( 望ましくない) です。
foo2()
とまったく同じように動作する方法はありfoo1()
ますか?
編集 2012-08-29
Josh O'Brien が以下のコメントで指摘したように、変動はおそらく遅延評価によって引き起こされます。
デバッグfoo1()
デバッグ トレーサーに入ります。<RETURN>
4回ヒットした後、次のように入力しますget("where")
。
<RETURN>
コンソールで、 1 回ヒットしてから次のように入力しますevList
。
入力Q
して現在のデバッグ実行を終了します
すべてをもう一度実行しますが、デバッグ呼び出しがわずかに異なります
コンソールで、<RETURN>
5 回ヒットしてから次のように入力しますevList
。
次のように入力しますget("where")
。
今where
指しているnamespace:methods
`foo2()' のデバッグ
デバッグ トレーサーに入ります。<RETURN>
4回ヒットした後、次のように入力しますget("where")
。
次に、<RETURN>
1回押してから次のように入力しますevList
。
入力Q
して現在のデバッグ実行を終了します
すべてをもう一度実行しますが、デバッグ呼び出しがわずかに異なります
<RETURN>
5回ヒットした後、次のように入力しますevList
。
次のように入力しますget("where")
。
前に実行したデバッグevList
と比較して、と の値が異なることに注意してください。where
と入力Q
して、現在のデバッグ実行を終了します。
これは私にはやや奇妙に思えますが、おそらく言語設計者の観点からは理にかなっています。where
に関連付けられた環境を指すように明示的に設定する方法がわかれば、おそらく大丈夫でしょうnamespace:methods
。
emacs - Emacs のレキシカル スコープ: 古い Emacsen との互換性
Emacs 24 では、ローカル変数のオプションのレキシカル バインディングが追加されました。XEmacs および以前の Emacs バージョンとの互換性を維持しながら、この機能をモジュールで使用したいと考えています。
Emacs 24 より前では、クロージャーを取得する最も簡単な方法は、 でlexical-let
定義されたフォームを使用することでした。このフォームはcl-macs
、巧妙なマクロトリックでレキシカル スコープをエミュレートしていました。これは elisp プログラマーの間であまり人気がありませんでしたが、lexical-let
次の疑似コードのように でラップすることを覚えていれば、実際に効果的なクロージャーを作成して機能しました。
問題は、Emacs 23 と XEmacs のサポートを維持しながら、新しいレキシカル バインディングを使用する最善の方法は何かということです。現在、バインドされているかどうかに応じlexical-let
て通常に展開または通常に展開するパッケージ固有のマクロを定義することで解決しました。let
lexical-binding
この解決策は機能しますが、新しい特別なフォームが非標準であり、適切に強調表示されず、 の下edebug
にステップインできず、通常はそれ自体に注意を引くため、ぎこちなく感じます。より良い方法はありますか?
編集
コードが引き続き標準フォームを使用してクロージャーを作成できるようにする、よりスマートな (必ずしも良いとは限らない) ソリューションのアイデアの 2 つの例を次に示します。
アドバイスまたはコンパイラ マクロを使用して、レキシカルスコープのシンボルへの割り当てのみを下に
lexical-let
展開します。このアドバイスは、 のバイトコンパイル中に一時的にのみアクティブになるため、残りの Emacs ではの意味は変更されません。let
lexical-bindings
lexical-let
foo.el
lexical-let
マクロ/コード ウォーカー機能を使用して、
let
プレフィックスのないシンボルをlexical-let
古い Emacsen にコンパイルします。これも、 のバイトコンパイル中にのみ適用されますfoo.el
。
これらのアイデアがオーバーエンジニアリングのにおいがしても心配しないでください。私はそれらをそのまま使用することを提案していません。上記のマクロに代わるものに興味があります。パッケージは、ローディング/コンパイルの複雑さを犠牲にして、クロージャーの移植性の高い使用の利点を得ることができます。
編集2
モジュールが残りの Emacs でモジュールを使用し続ける、let
またはそれらを壊すことなく使用できるようにするソリューションを誰も提供していないため、上記のマクロがlexical-let
それを行う方法であると述べている Stefan の回答を受け入れます。それに加えて、edebug と lisp-indent のエレガントな宣言を使用および追加することで、コードが改善されます。bound-and-true-p
誰かがこの互換性レイヤーの代替提案、または上記のアイデアの洗練された実装を持っている場合は、回答することをお勧めします.
javascript - Javascriptにはどのようなタイプのスコープが存在しますか?
グローバルスコープと、さらにネスト可能な機能スコープがあることを理解しています。しかし、Javascript には他のタイプのスコープやクロージャがありますか?
このトピックに取り組んでいますが、スコープとクロージャーの違いは何ですか?
javascript - jQuery.getJSON から JSON blob を返す
バックエンド アクションの内容を含む JSON blob を返す MVC コントローラーを呼び出す関数があります。この JSON BLOB は、エンド ユーザーに表示されるテーブルに入力するために使用されています。
私の関数は現在、次のようになっています。
...そして、次のような呼び出しアクション:
これを呼び出す Web ページ/アクションを実行すると、指定された順序で次の結果が得られます。
他の構成 (.getJSON() の .complete、$.getJSON() から値を直接返す) を試みて、コールバックからの「データ」を外側のスコープの blob 変数にエコーしようとしましたが、これまでのところ、ブロブは getJSON コールバック内でのみ値を持つように見えます。
そうは言っても、JavaScript はレキシカル スコープの言語であることも認識しているため、すべての匿名関数チェーンが実行される可能性があります。
質問: 私の blob が $.getJSON 内に正しく表示されていることがわかります。では、ブロブを取り出すにはどうすればよいでしょうか。
javascript - ブロックスコープがない場合、独立したブロックのポイントは何ですか?
このように独立したブロックを使用することが許可されています...
これは、http: //eloquentjavascript.net/chapter3.html#p3c7ae609からのものです。
しかし、そのようなブロックを持つことのポイントは何ですか? それはどのような目的に役立ちますか?
scheme - SICPの環境評価モデルの観点からの字句的スコープと動的スコープ
SICPのセクション3.2.2で、次のコードの実行
この図で説明されています。
関数が適用されるたびに、シンボルと値の間のバインディングのセットを表す新しいフレームが作成されます( E1
throughでラベル付けされます)。E4
シンボルがフレームにバインドされていない場合、そのフレームを囲む環境は、その特定のシンボルのバインドについて照会されます。
この図の興味深い点は、でラベル付けされたすべてのフレームE
がグローバル環境に含まれていることです。これは、関数がグローバル環境で定義されているためであると説明されていますが、この問題については詳しく説明されていません。
によって作成された各フレームは、プロシージャオブジェクト
square
によって示される環境であるため、グローバル環境を指していることに注意してください。square
代わりに、関数が呼び出された環境に含まれているフレーム、たとえば、に含まれているフレームが含まれている場合、E3
それE2
はE1
動的スコープの言語がどのように機能するかの有効なモデルでしょうか?また、Schemeは字句スコープであるため、ダイアグラム内のフレームが同じ「親」環境を持つ方法はありますか?