【问题标题】:What is the difference between Methods and Attributes in Ruby?Ruby中的方法和属性有什么区别?
【发布时间】:2010-11-14 17:46:31
【问题描述】:

你能举个例子吗?

【问题讨论】:

    标签: ruby attributes methods


    【解决方案1】:

    属性只是一个捷径。如果您使用attr_accessor 创建属性,Ruby 只需声明一个实例变量并为您创建getter 和setter 方法。

    既然你问了一个例子:

    class Thing
        attr_accessor :my_property
    
        attr_reader :my_readable_property
    
        attr_writer :my_writable_property
    
        def do_stuff
            # does stuff
        end
    end 
    

    这是你如何使用这个类:

    # Instantiate
    thing = Thing.new
    
    # Call the method do_stuff
    thing.do_stuff
    
    # You can read or write my_property
    thing.my_property = "Whatever"
    puts thing.my_property
    
    # We only have a readable accessor for my_readable_property
    puts thing.my_readable_property 
    
    # And my_writable_propety has only the writable accessor
    thing.my_writable_property = "Whatever"
    

    【讨论】:

      【解决方案2】:

      属性是对象的特定属性。方法是对象的能力。

      在 Ruby 中,所有实例变量(属性)默认都是私有的。这意味着您无法在实例本身范围之外访问它们。 访问属性的唯一方法是使用访问器方法。

      class Foo
        def initialize(color)
          @color = color
        end
      end
      
      class Bar
        def initialize(color)
          @color = color
        end
      
        def color
          @color
        end
      end
      
      class Baz
        def initialize(color)
          @color = color
        end
      
        def color
          @color
        end
      
        def color=(value)
          @color = value
        end
      end
      
      f = Foo.new("red")
      f.color # NoMethodError: undefined method ‘color’
      
      b = Bar.new("red")
      b.color # => "red"
      b.color = "yellow" # NoMethodError: undefined method `color=' 
      
      z = Baz.new("red")
      z.color # => "red"
      z.color = "yellow"
      z.color # => "yellow"
      

      因为这是一种非常常见的行为,Ruby 提供了一些方便的方法来定义访问器方法:attr_accessorattr_writerattr_reader

      【讨论】:

      • 您始终可以使用 Object.instance_variable_get(:@symbol) 访问变量,从而避免了定义访问器的需要。
      • 这不是一个好习惯。 ;) instance_variable_get 应该保留给元编程的东西。这就像将一个方法定义为私有然后使用 send(:method) 访问它。
      【解决方案3】:

      属性,严格来说,是类实例的实例变量。更一般地说,属性通常使用 attr_X 类型的方法声明,而方法则按原样声明。

      一个简单的例子可能是:

      attr_accessor :name
      attr_reader :access_level
      
      # Method
      def truncate_name!
        @name = truncated_name
      end
      
      # Accessor-like method
      def truncated_name
        @name and @name[0,14]
      end
      
      # Mutator-like method
      def access_level=(value)
        @access_level = value && value.to_sym
      end
      

      这两者之间的区别在 Ruby 中有些随意,因为没有专门提供对它们的直接访问。这与其他语言(如 C、C++ 和 Java)形成鲜明对比,其中对象属性的访问和调用方法是通过两种不同的机制完成的。尤其是 Java 具有这样拼写出来的访问器/修改器方法,而在 Ruby 中,这些是通过名称来暗示的。

      通常情况下,如示例中所示,“属性访问器”和根据属性值提供数据的实用程序方法(例如 truncated_name)之间的差异很小。

      【讨论】:

        【解决方案4】:
        class MyClass
          attr_accessor :point
        
          def circle
            return @circle
          end
        
          def circle=(c)
            @circle = c
          end
        end
        

        属性是对象的属性。在这种情况下,我使用 attr_accessor 类方法来定义 :point 属性以及 point 的隐式 getter 和 setter 方法。

        obj = MyClass.new
        obj.point = 3
        puts obj.point
        > 3
        

        方法“circle”是@circle 实例变量显式定义的getter。 'circle=' 是为 @circle 实例变量显式定义的设置器。

        【讨论】:

          【解决方案5】:

          我听说“属性”这个词在 Ruby 特定的圈子中指的是任何不带参数的方法。

          class Batman
          
            def favorite_ice_cream
               [
                 'neopolitan', 
                 'chunky monkey', 
                 'chocolate', 
                 'chocolate chip cookie dough', 
                 'whiskey'
               ].shuffle[0]         
            end
          
          end
          

          在上面,my_newest_batman.favorite_ice_cream 将是一个属性。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-05-26
            • 2018-09-07
            • 1970-01-01
            • 2013-11-11
            • 2012-04-28
            相关资源
            最近更新 更多