57676

[code]

    5.times do
        def a
            x = rand(1..10).to_f
            p "x = " << x.to_s
            return @a_result if @a_result
            @a_result = (40 + 20 + 34) / x
        end
    
        def b
            return @b_result if @b_result
            @b_result = a * 2
        end
    
        def c
            return @c_result if @c_result
            @c_result = b.to_f / 2
        end
    
        p a, b, c
    end
    
[/code]

上記のようなコードでaとbを計算した場合、5回とも同じ値になってしまいます。  
return @～ が繰り返しで同じ値になってしまうのが問題なのは分かるのですがどのようにしたら良いのか分からず困っています。  
上の計算くらいであれば良いのですが、もっと複雑なものになると時間が掛かるので、できる限り速く計算したいため a,b
を一度求めたらその値をそのまま使い、1巡したらa,b,cの値をリセットしたいのですが、何か良い方法はあるのでしょうか。  
説明が下手で申し訳ありませんが教えて頂けるとありがたいです。  
よろしくお願いします。


CC BY-SA 4.0
2019-08-29T02:18:50.167
57670
2019-08-29T04:07:44.067
2019-08-29T04:07:44.067
29428
29428
question
ruby
returnを使用した計算について


クラスにしてしまうのがよいかなと思いました

[code]

    class A
      def a
        return @a_result if @a_result
        x = rand(10).to_f
        p "x = " << x.to_s
        @a_result = (40 + 20 + 34) / x
      end
    
      def b
        return @b_result if @b_result
        @b_result = a * 2
      end
    
      def c
        return @c_result if @c_result
        @c_result = b.to_f / 2
      end
    
      def print
        p a, b, c
      end
    end
    
    5.times do
      A.new.print
    end
    
[/code]


CC BY-SA 4.0
2019-08-29T02:45:53.160
57674
2019-08-29T02:45:53.160
35637
57670
answer


与えられたコードですと、グローバルに(より正確には、`Object`クラスに) `a`, `b`, `c`
メソッドを定義していることになり、これは、いろいろと問題が発生する可能性が高いです。

@えむけー さんが仰っているように、それ専用のクラスを用意する方が良いと思います。また、今回のような、一度だけ計算したい、ということを実現するにあたって、
ruby でよく使われるのは `||=` のオペレータだと思っています。

なので、自分がこの処理を記述するとするならば、

[code]

    class Calculator
      def a
        @a ||=
          begin
            x = rand(10).to_f
            p "x = " << x.to_s
            (40 + 20 + 34) / x
          end
      end
    
      def b
        @b ||= a * 2
      end
    
      def c
        @c ||= b.to_f / 2
      end
    end
    
    5.times do
      calculator = Calculator.new
      calculator.instance_eval do
        p a, b, c
      end
    end
    
[/code]

みたいな形になると思います。


CC BY-SA 4.0
2019-08-29T03:08:49.083
57676
2019-08-29T03:08:49.083
754
57670
answer