+1

Ruby Contructors

  1. Giới thiệu

    'Visual Basic .NET
    Dim sf As BaseballTeam = New BaseballTeam("San Francisco Giants")
    
    'Dim - Allocates space for one or more variables
    'As  - Identifies a data type in a declaration
    'New - Creates a new object instace
    
    #Ruby
    sf = BaseballTeam.new("San Francisco Giants")
    
    #Ruby is not strictly typed so there's no need to identify the data type.
    #Object.new is a class method which allocates space and create an instance of the class.
    

    Rất nhiều ngôn ngữ sử dụng từ khóa new, cái mà trong Ruby không sử dụng để khởi tạo 1 instance object. Thay vào đó, Ruby cung cấp 1 method 'new' để gọi trực tiếp đến class.

  2. Trách nhiệm của Ruby Contructor Ruby Contructor có 3 việc cần phải thực hiện:

    • Phân phát không gian cho object
    • Chỉ định các biến instances với các giá trị khởi tạo
    • Trả về instance object của class
    class Foo
     def initialize(bar, biz)
       @bar = bar
       @biz = biz
     end
    end
    
    foo = Foo.new("a", "b")
    
  3. #initialize vs .new

    class Foo
      def initialize(bar, biz)
        @bar = bar
        @biz = biz
      end
    end
    
    foo = Foo.new("a", "b")
    

    #initialize là 1 instance method .new là 1 class method Để làm rõ .new là ruby contructor không phải là instance method #initialize, chúng ta hãy xem lại 3 việc mà hàm khởi tạo phải làm ở phía trên. Thì .new thực hiện các công việc đó, còn #initialize được sử dụng chỉ để chỉ định các biến instances với các giá trị khởi tạo. Chúng ta có thể minh họa hàm new theo cách riêng của chúng ta như sau:

    class Foo
      def self.new_object(*args)
        instance = allocate
        instance.send(:initialize, *args)
        instance
      end
    
      def initialize(bar, biz)
        @bar = bar
        @biz = biz
      end
    end
    
    >> Foo.new(1,2)        #=> #<Foo:0x007fac3e15d0a0 @bar=1, @biz=2>
    >> Foo.new_object(1,2) #=> #<Foo:0x007fac3e206420 @bar=1, @biz=2>
    
  4. Overloading Contructor và cách khắc phục

    class Circle
      attr_accessor :radius, :area
      
      #=> Custom Constructors
      def self.new_by_radius(*args)
        circle = allocate
        circle.init_radius(*args)
        circle
      end
    
      def self.new_by_area(*args)
        circle = allocate
        circle.init_area(*args)
        circle
      end
    
      #=> Custom Initializers
      def init_radius(_radius)
        @radius = _radius * 1.0
        @area = 3.14 * (@radius ** 2)
      end
    
      def init_area(_area)
        @area = _area * 1.0
        @radius = Math.sqrt(@area / 3.14)
      end
    end
    

    Một trong những điều mà chúng ta vẫn thường hay không để ý đó là việc overloading contructor trong ruby. Việc chúng ta khởi tạo quá nhiều biến khởi tạo mà không dùng đến dẫn đến thừa thãi bộ nhớ và không gian lưu các biến đó, tuy không có gì quá to tát nhưng nó khiến bạn hiểu sâu hơn và giúp bạn improve code tốt hơn

  5. Tổng kết Đây là những gì mình hiều về contructor trong Ruby, hi vọng sẽ giúp được phần nào cho các bạn đang muốn tìm hiểu về nó. 😄


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí