ホームページ  >  に質問  >  本文

ruby -- 全局和局部问题

n = 5
def num
  puts n
end

为什么是错的的?
我知道全局和局部基本原理。
局部变量在函数里只能使用,在外部是不存在。

但是在python或js里使用这样方式可以执行的!
还是只有ruby要在函数使用变量需要重新宣告。

请问各位可以解释吗?
谢谢

黄舟黄舟2712日前714

全員に返信(6)返信します

  • 黄舟

    黄舟2017-04-22 09:01:49

    def は新しいスコープを開きます

    リーリー

    nにアクセスしたい場合は、フラット化スコープを使用する必要があります

    リーリー

    返事
    0
  • 大家讲道理

    大家讲道理2017-04-22 09:01:49

    リーリー

    私も初心者なので、他の専門家の意見を見てみましょう。

    返事
    0
  • 迷茫

    迷茫2017-04-22 09:01:49

    ただし、Python または JS でこのメソッドを使用して実行できます。

    Python では読み取り専用


    以下は、Ruby がなぜこれを行ったのかについての推測です。

    Ruby の def によって生成されたメソッドは、グローバル変数にのみアクセスできます。
    define_method で生成されたメソッドと -> (param) {} または lambda { |param| で生成された proc にアクセスできます。外部変数。 def 生成的方法只能访问全局变量。
    define_method 生成的方法 和 -> (param) {}lambda { |param| } 生成的 proc 带闭包,可以访问外层变量。

    我猜想是因为 Ruby 认为最常用的情况是你不需要访问外层变量,所以 def 不给你访问了,这样的好处:

    • 不会像 js 一样无意中搞乱外层变量。JavaScript 中为了避免这一点,都要在 function 头部把体内用到的变量都 undefined 一下,很罗嗦。
    • 不用创建闭包,节省开销。

    至于 lambda 带闭包那很正常,都 lambda 了不带闭包说的过去吗?

    至于 define_method,猜想是因为

    • define_method 因为是所谓元编程,有更大机率用外层变量,(本来用元编程就是偷懒少打字,要是不能用外层变量,还要作为参数传入,那累死了。)所以就带闭包。
    • method 定义不能带闭包有时候会不方便,但是通常也不需要,所以就让长一点的 define_method 带闭包啰。
    • define_method 除了 define_method (symbol) { |param| },还可以写成 define_method(symbol, method),其中 method 比较常用的就是传入一个 lambda,既然传入 lambda,如果本身 define_method
    • 最も一般的な状況は外部変数にアクセスする必要がないことであると Ruby が考えているためだと思います。そのため、def にはアクセスが許可されません。これには次のような利点があります。
      • js のように意図せずに外部変数をいじることはありません。 JavaScript でこれを回避するには、本文で使用されるすべての変数を function ヘッダーで未定義にする必要がありますが、これは非常に冗長です。
    • クロージャを作成する必要がないため、オーバーヘッドが節約されます。 🎜 🎜 🎜クロージャのあるラムダについては、クロージャなしでラムダを使用しても問題ありませんか? 🎜 🎜 define_method に関しては、おそらく次の理由があると思います🎜
        <リ> define_method いわゆるメタプログラミングなので、外部変数を使用する可能性が高くなります (本来、メタプログラミングを使用すると、入力が少なくなるという意味です。外部変数を使用できず、外部変数を渡す必要がある場合)。パラメータとして使用すると、大変になります。) そこで、クロージャを使用します。 🎜
      • メソッド定義にクロージャを含めることができないと不便な場合がありますが、通常はその必要はないため、長い define_method にクロージャを持たせます。 🎜 <リ> define_method define_method (symbol) { |param| } に加えて、define_method(symbol, method) としても記述できます。 code>method は、ラムダを渡すためによく使用されます。ラムダが渡されるため、define_method にクロージャーがないと非常に不整合になるため、そうさせます。 🎜 🎜

        返事
        0
  • 伊谢尔伦

    伊谢尔伦2017-04-22 09:01:49

    @Andrew_375683 が正しいです。
    主に範囲の問題です
    しかし、これを解決する簡単な方法があります。nを関数に変えるだけです

    リーリー

    返事
    0
  • 巴扎黑

    巴扎黑2017-04-22 09:01:49

    この質問は非常に人気があります。ちょうどそこに行ったところですが、戻ってきたときに数人が応答してくれました。

    コード内の n はグローバル変数だと思っていますが、残念ながらそうではありません

    リーリー

    変更する必要がある場合は、プレフィックスとして $ を追加してください:

    リーリー

    美しいルビーの中に、$がとても目を引きます。 Ruby の上司はグローバル変数が不可欠であることを知っていますが、悪用されることも恐れているので、ちょっとしたいたずらをします;)。 Ruby の変数スコープの知識が必要になります。Ruby の利点は複雑かつ独特です。

    @andrewzhyl よく言われます、いいね。

    返事
    0
  • 高洛峰

    高洛峰2017-04-22 09:01:49

    注意: def と def_method の違い: def はメソッドを定義するために使用されるキーワードであり、def_method の機能は新しいメソッドを生成することです (@ のみ)。そして (美しい変数); そして、define_method はよりオープンで、何も変更せずに友達に会うことに積極的です。

    返事
    0
  • キャンセル返事