【问题标题】:Ruby equivalents for PHP's magic methods __call, __get and __setPHP 魔术方法 __call、__get 和 __set 的 Ruby 等效项
【发布时间】:2010-08-16 14:36:38
【问题描述】:

我很确定 Ruby 有这些(__call、__get__set 的等价物),否则 find_by 将如何在 Rails 中工作?也许有人可以举一个简单的例子来说明如何定义与 find_by 相同的方法?

谢谢

【问题讨论】:

    标签: ruby-on-rails ruby dynamic-method


    【解决方案1】:

    总之你可以映射

    • __call to a method_missing call with arguments
    • __设置为方法名称以“=”结尾的 method_missing 调用
    • __get 到没有任何参数的 method_missing 调用

    __调用

    php

    class MethodTest {
      public function __call($name, $arguments) {
        echo "Calling object method '$name' with " . implode(', ', $arguments) . "\n";
      }
    }
    
    $obj = new MethodTest;
    $obj->runTest('arg1', 'arg2');
    

    红宝石

    class MethodTest
      def method_missing(name, *arguments)
        puts "Calling object method '#{name}' with #{arguments.join(', ')}"
      end
    end
    
    obj = MethodTest.new
    obj.runTest('arg1', 'arg2')
    

    __set 和 __get

    php

    class PropertyTest {
      //  Location for overloaded data.
      private $data = array();
    
      public function __set($name, $value) {
        echo "Setting '$name' to '$value'\n";
        $this->data[$name] = $value;
      }
    
      public function __get($name) {
        echo "Getting '$name'\n";
        if (array_key_exists($name, $this->data)) {
          return $this->data[$name];
        }
      }
    }
    
    $obj = new PropertyTest;
    $obj->a = 1;
    echo $obj->a . "\n";
    

    红宝石

    class PropertyTest
    
      # Location for overloaded data.
      attr_reader :data
      def initialize
        @data = {}
      end
    
      def method_missing(name, *arguments)
        value = arguments[0]
        name = name.to_s
    
        # if the method's name ends with '='
        if name[-1, 1] == "="
    
          method_name = name[0..-2]
          puts "Setting '#{method_name}' to '#{value}'"
          @data[method_name] = value
    
        else
    
          puts "Getting '#{name}'"
          @data[name]
    
        end
      end
    
    end
    
    obj = PropertyTest.new
    obj.a = 1 # it's like calling "a=" method : obj.a=(1)
    puts obj.a
    

    【讨论】:

      【解决方案2】:

      动态查找器是通过实现方法缺失来完成的

      http://ruby-doc.org/core/classes/Kernel.html#M005925

      看看这篇博文,它会让你了解它们的工作原理。

      http://blog.hasmanythrough.com/2006/8/13/how-dynamic-finders-work

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-10
        • 2011-06-02
        • 1970-01-01
        • 2012-04-05
        • 1970-01-01
        • 2010-12-09
        • 2011-04-26
        相关资源
        最近更新 更多