$&グローバル変数を使用するプログラムによるエイリアスメソッド

シュニーム

Rubyの特殊を使用するメソッドのエイリアスを作成しようとしています$&最後の正規表現の一致を返します)。私はこれを手動で行うことができ、それは機能します:

original = String.instance_method(:sub)
String.send(:define_method, :sub) do |*args, &block|
  puts "called"
  original.bind(self).call(*args, &block)
end
"foo".sub(/f/) { $&.upcase }
  called
  # => "Foo"

ただし、これを実行するメソッドを作成しようとすると、失敗します。

def programatic_alias(klass, method_name)
  original = klass.instance_method(method_name)
  klass.send(:define_method, method_name) do |*args, &block|
    puts "called"
    original.bind(self).call(*args, &block)
  end
end

programatic_alias(String, :sub)
"foo".sub(/f/) { $&.upcase }
  called
  NoMethodError: undefined method `upcase' for nil:NilClass
  called
  called
  called
    from (irb):19:in `block in irb_binding'

グローバル状態がprogramatic_aliasメソッドのスコープの影響を受けているように見えますが、それが起こっているかどうかはわかりません。質問はこれです:String#subRubyの特別なグローバル変数で引き続き機能するようにプログラムでエイリアスを作成するにはどうすればよいですか?

フレデリック・チャン

私の知る限り、これはできません。ドキュメントは言います

これらのグローバル変数は、スレッドローカル変数とメソッドローカル変数です。

ルビーソースを掘り下げると、からデータを取得する$&呼び出しにアクセスします。この呼び出しは、現在の制御フレームを取得し、そこからデータを読み取ります(さらにいくつかの内部メソッドをスキップします)。このデータはいずれもrubyapiに公開されていません。このデータを1つのフレームからアクセスしたいフレームに伝播する方法はありません。last_match_getterrb_backref_getvm_svar_get

2番目の例では、元のメソッドの呼び出しがメソッド内で行われているprogramatic_aliasため$&、そのスコープに設定されています。同じ理由で

'foo'.try(:sub, /f/) {$&.upcase}

どちらも機能しません。

最初の例の半分subは、呼び出される場所$&と参照される場所(ブロック内)が同じメソッドスコープ(この場合はルビーのトップレベル)にあるため、機能します。次のように変更します。

original = String.instance_method(:sub)
String.send(:define_method, :sub) do |*args, &block|
  puts "called"
  original.bind(self).call(*args, &block)
end

def x
  "foo".sub(/f/) { $&.upcase }
end

x()

そして$&、もはや(あなたがキャッチした場合によってスローされた例外あなたのブロックで定義されていないxあなたはそれを見ることができる$&トップレベルに設定されています)

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

グローバル変数を使用せずに関数内でPHPクラスメソッドを使用するにはどうすればよいですか?

分類Dev

(静的)メソッドでローカル変数にJava CDI管理Beanをプログラムで注入する方法

分類Dev

Pythonのすべてのクラスメソッドにグローバル変数を使用するにはどうすればよいですか?

分類Dev

クエリのOracleストアドプロシージャでグローバル変数を使用する方法

分類Dev

タイプエラーメッセージなしでOBJLoaderを使用してオブジェクトのグループをグローバル変数にロードするにはどうすればよいですか?

分類Dev

更新されたグローバルクラス変数をあるメソッドから別のメソッドにどのように渡しますか?

分類Dev

グローバル変数初期化のウォームアップリクエストを実装する方法

分類Dev

グローバルJSメソッドでAxiosリクエストをインターセプトする

分類Dev

事前定義されたメソッドを使用せずに10進数を2進数に変換するJavaコンソールプログラム(for)

分類Dev

アンドロイドグーグルマップのパスをカバーするためにカメラをズームする方法は?

分類Dev

XML-RPCを使用してデータを特定のドメインに送信するプログラムからデータをリバースエンジニアリングするにはどうすればよいですか?

分類Dev

プログラムクラス(コンソールアプリ)の変数にアクセスする方法

分類Dev

フラッターのパスワードをグローバルに比較するためのプログラムによるアプローチ?

分類Dev

マルチスレッドを使用するプログラムをブロッキングキューを使用するプログラムに変える

分類Dev

ドローアブルリソースによるアプリのパッキングエラー

分類Dev

NodeJS-Core NodeJSと元のNodeソリューションを使用したプログレスバーによるファイルのアップロード

分類Dev

Tkinterプログラムから変数をリアルタイムで自動的にプロットする方法

分類Dev

メソッドでグローバル変数をローカル変数に変換するJavaの利点

分類Dev

socketioメソッドでグローバルピラミッドリクエストを取得するにはどうすればよいですか?

分類Dev

ヘルムエラー:リリースをアップグレードするには、ロールバックが必要です

分類Dev

クラスのメソッドからグローバル変数に出力を取得するにはどうすればよいですか?

分類Dev

パズルソルバープロローグプログラムのマトリックスを生成する

分類Dev

クラスメソッドでグローバルクラス変数を作成する方法

分類Dev

アドレスバーのカスタム「エイリアス」(「デスクトップ」や「プログラム ファイル」など) で場所を自動的に開くように Windows ファイル エクスプローラーを設定する方法は?

分類Dev

ファクトリメソッドとメソッドリファレンス(シングルトン/プロトタイプ)でラムダを使用すると、関数型インターフェイスの初期化が異なる理由

分類Dev

プログラムでOSXバッテリーメニューバーアイテムを非表示にする

分類Dev

どのようにアンドロイドのJavaでのエラー「マッチング方法のパラメータを持っている必要があります、クエリ内の各バインド変数」を修正するには?

分類Dev

静的メソッドからグローバル非静的変数にアクセスする方法

分類Dev

リストの変数をPrologプログラミングでグローバル変数にする方法は?

Related 関連記事

  1. 1

    グローバル変数を使用せずに関数内でPHPクラスメソッドを使用するにはどうすればよいですか?

  2. 2

    (静的)メソッドでローカル変数にJava CDI管理Beanをプログラムで注入する方法

  3. 3

    Pythonのすべてのクラスメソッドにグローバル変数を使用するにはどうすればよいですか?

  4. 4

    クエリのOracleストアドプロシージャでグローバル変数を使用する方法

  5. 5

    タイプエラーメッセージなしでOBJLoaderを使用してオブジェクトのグループをグローバル変数にロードするにはどうすればよいですか?

  6. 6

    更新されたグローバルクラス変数をあるメソッドから別のメソッドにどのように渡しますか?

  7. 7

    グローバル変数初期化のウォームアップリクエストを実装する方法

  8. 8

    グローバルJSメソッドでAxiosリクエストをインターセプトする

  9. 9

    事前定義されたメソッドを使用せずに10進数を2進数に変換するJavaコンソールプログラム(for)

  10. 10

    アンドロイドグーグルマップのパスをカバーするためにカメラをズームする方法は?

  11. 11

    XML-RPCを使用してデータを特定のドメインに送信するプログラムからデータをリバースエンジニアリングするにはどうすればよいですか?

  12. 12

    プログラムクラス(コンソールアプリ)の変数にアクセスする方法

  13. 13

    フラッターのパスワードをグローバルに比較するためのプログラムによるアプローチ?

  14. 14

    マルチスレッドを使用するプログラムをブロッキングキューを使用するプログラムに変える

  15. 15

    ドローアブルリソースによるアプリのパッキングエラー

  16. 16

    NodeJS-Core NodeJSと元のNodeソリューションを使用したプログレスバーによるファイルのアップロード

  17. 17

    Tkinterプログラムから変数をリアルタイムで自動的にプロットする方法

  18. 18

    メソッドでグローバル変数をローカル変数に変換するJavaの利点

  19. 19

    socketioメソッドでグローバルピラミッドリクエストを取得するにはどうすればよいですか?

  20. 20

    ヘルムエラー:リリースをアップグレードするには、ロールバックが必要です

  21. 21

    クラスのメソッドからグローバル変数に出力を取得するにはどうすればよいですか?

  22. 22

    パズルソルバープロローグプログラムのマトリックスを生成する

  23. 23

    クラスメソッドでグローバルクラス変数を作成する方法

  24. 24

    アドレスバーのカスタム「エイリアス」(「デスクトップ」や「プログラム ファイル」など) で場所を自動的に開くように Windows ファイル エクスプローラーを設定する方法は?

  25. 25

    ファクトリメソッドとメソッドリファレンス(シングルトン/プロトタイプ)でラムダを使用すると、関数型インターフェイスの初期化が異なる理由

  26. 26

    プログラムでOSXバッテリーメニューバーアイテムを非表示にする

  27. 27

    どのようにアンドロイドのJavaでのエラー「マッチング方法のパラメータを持っている必要があります、クエリ内の各バインド変数」を修正するには?

  28. 28

    静的メソッドからグローバル非静的変数にアクセスする方法

  29. 29

    リストの変数をPrologプログラミングでグローバル変数にする方法は?

ホットタグ

アーカイブ