18026


例えば以下のクラスCでsayメソッドを使ったら  
インスタンス変数@dはnilで初期化されています．

このメソッドは３行にわたって書いており，  
もうすこしスマートに書けないかと悩んでいます．

すでに機能的には充足されていますが，  
rubyらしく書くためにはどう工夫すればよいでしょうか

[code]

    class C
      def initialize
        @d = "hello"
      end
      def say
        result = @d
        @d = nil
        result
      end
    end
    
    c = C.new
    c.say #=> hello
    c.say #=> nil
    
[/code]


CC BY-SA 3.0
2015-10-24T13:25:20.043
18025
2015-10-26T02:13:50.253
8722
question
ruby
インスタンス変数を参照したら，また初期化したい


`tap`を使うと良いと思います。

[code]

    def say
      @d.tap { @d = nil }
    end
    
[/code]


CC BY-SA 3.0
2015-10-24T15:14:30.187
18026
2015-10-24T15:14:30.187
9575
18025
answer


どうしても `@d` は文字列じゃないといけない、という制約がないのであれば、配列を使うのもアリかもです。（外から見た動きは文字列の場合と同じになります）

[code]

    class C
      def initialize
        @d = ["hello"]
      end
      def say
        @d.pop
      end
    end
    
[/code]


CC BY-SA 3.0
2015-10-24T23:09:42.550
18034
2015-10-24T23:09:42.550
85
18025
answer


インスタンス変数を取り除くメソッドを使用するという手もあります。

[code]

    def say
      remove_instance_variable(:@d) if @d
    end
    
[/code]

[Object#remove_instance_variable](http://docs.ruby-
lang.org/ja/2.2.0/class/Object.html#I_REMOVE_INSTANCE_VARIABLE)


CC BY-SA 3.0
2015-10-25T01:52:46.547
18037
2015-10-25T01:52:46.547
9608
18025
answer

[code]

    class C
      def initialize
        @d = "hello"
      end
    
      def say
        @d
      ensure
        @d = nil
      end
    end
    
[/code]


CC BY-SA 3.0
2015-10-26T02:11:51.113
18073
2015-10-26T02:11:51.113
2599
18025
answer

[code]

    class C
      def initialize
        @d = "hello"
      end
    
      def say
        result, @d = @d
        result
      end
    end
    
[/code]


CC BY-SA 3.0
2015-10-26T02:13:50.253
18074
2015-10-26T02:13:50.253
2599
18025
answer