Static variables in ruby, like in C functions

前端 未结 6 1640
花落未央
花落未央 2021-01-22 08:29

Is there any such thing as static variables in Ruby that would behave like they do in C functions?

Here\'s a quick example of what I mean. It prints \"6\\n7\\n\" to the

相关标签:
6条回答
  • 2021-01-22 08:49

    You can use a global variable:

    $a = 5
    def test
      $a += 1
    end
    
    p test #=> 6
    p test #=> 7
    
    0 讨论(0)
  • 2021-01-22 08:57

    Similar to nicooga's answer but more self-contained:

    def some_method
      @var ||= 0
      @var += 1
      puts @var
    end
    
    0 讨论(0)
  • 2021-01-22 09:00

    Scope your variable in a method and return lambda

    def counter
      count = 0
      lambda{count = count+1}
    end
    
    test = counter
    test[]
    #=>1
    test[]
    #=>2
    
    0 讨论(0)
  • 2021-01-22 09:02

    There is no syntactical equivalent to C's static variables in Ruby, and I've never seen something like that in languages with similar level of abstraction, like Javascript, Python, Elixir, etc.

    What I understand about this C code is that the first time the function is called the compiler initializes the variable with the initial value. Subsequent calls will just get the current value of the varible.

    This is how I would translate the same logic in ruby terms:

    def test()
      @a ||= 5 # If not set, set it. We need to use an instance variable to persist the variable across calls.
      @a += 1 # sum 1 and return it's value
    end
    
    def main()
      puts test
      puts test
      0
    end
    

    This works outside a class too.

    0 讨论(0)
  • 2021-01-22 09:02

    I think a standard way to do this is to use Fiber.

    f = Fiber.new do
      a = 5
      loop{Fiber.yield a += 1}
    end
    
    puts f.resume # => 6
    puts f.resume # => 7
    ...
    
    0 讨论(0)
  • 2021-01-22 09:05

    Use a variable in the singleton class (The static class itself)

    class Single
      def self.counter
        if @count  
          @count+=1
        else
          @count = 5
        end
      end
    end
    

    In ruby, any class is an object which has only one instance. Therefore, you can create an instance variable on the class, and it will work as a "static" method ;)

    Output:

      ruby 2.5.5p157 (2019-03-15 revision 67260) [x86_64-linux]
    
    => :counter
       Single.counter
    => 5
       Single.counter
    => 6
       Single.counter
    => 7
    

    To get this behaviour on the main scope, you can do:

    module Countable
      def counter
        if @count  
          @count+=1
        else
          @count = 5
        end
      end
    end
    
    => :counter
       self.class.prepend Countable # this "adds" the method to the main object
    => Object
       counter
    => 5
       counter
    => 6
       counter
    => 7
    
    0 讨论(0)
提交回复
热议问题