Setter method (assignment) with multiple arguments

后端 未结 2 1812
攒了一身酷
攒了一身酷 2020-12-10 02:17

I have a custom class and want to be able to override the assignment operator. Here is an example:

class MyArray < Array
  attr_accessor :direction
  def          


        
相关标签:
2条回答
  • 2020-12-10 03:00

    The problem is

    def strategy=(strategy, direction = :forward)
      @strategy = strategy
      @strategy.direction = direction
    end
    

    When you set

    h.strategy = :mystrategy, :backward
    

    you are actually overriding the original @strategy instance. After that call, @strategy is an instance of Symbol, not MyArray.

    What do you want to do? Replace the object or update it?

    0 讨论(0)
  • 2020-12-10 03:14

    Due to the syntax sugar of methods whose names end in=, the only way that you can actually pass multiple parameters to the method is to bypass the syntax sugar and use send

    h.send(:strategy=, :mystrategy, :backward )
    

    …in which case you might as well just use a normal method with better names:

    h.set_strategy :mystrategy, :backward
    

    However, you could rewrite your method to automatically un-array the values if you knew that an array is never legal for the parameter:

    def strategy=( value )
      if value.is_a?( Array )
        @strategy << value.first
        @strategy.direction = value.last
      else
        @strategy = value
      end
    end
    

    This seems like a gross hack to me, however. I would use a non-assigment method name with multiple arguments if you need them.


    An alternative suggestion: if the only directions are :forward and :backward what about:

    def forward_strategy=( name )
      @strategy << name
      @strategy.direction = :forward
    end
    
    def reverse_strategy=( name )
      @strategy << name
      @strategy.direction = :backward
    end
    
    0 讨论(0)
提交回复
热议问题