Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Ruby

Thành thạo Ruby: Sử dụng từ khóa Alias để tạo bí danh phương thức

Trong Ruby, bạn có thể đặt tên thay thế cho một phương thức theo hai cách:

  • Từ khóa alias
  • Phương thức alias_method

Vì chúng làm cùng một việc nhưng theo cách hơi khác nhau, nên chủ đề này thường gây nhầm lẫn.

Hình ảnh dưới đây tóm tắt các khác biệt:

Thành thạo Ruby: Sử dụng từ khóa Alias để tạo bí danh phương thức

Hãy cùng khám phá chi tiết những khác biệt này để hiểu rõ hơn!

Từ khóa alias

Trước hết là alias, một từ khóa của Ruby (giống như if, def, class, v.v.)

Cú pháp của nó như sau:

 alias print_something puts
print_something 1 

Bây giờ việc gọi print_something tương đương với gọi puts.

Vì alias là từ khóa nên nó có một số đặc điểm thú vị:

  • Có cú pháp đặc biệt
  • Có thể sử dụng ở bất kỳ đâu trong code
  • Có thể tạo bí danh cho biến toàn cục (không nên làm vậy!)

Các dạng hợp lệ của alias:

  • alias a b
  • alias :a :b
  • alias :"#{}":b

Lưu ý rằng không có dấu phẩy giữa các đối số như phương thức thông thường.

Ruby mong đợi cả a và b là tên phương thức hợp lệ, biến không hoạt động ở đây. Nếu muốn dùng biến, bạn phải làm như sau…

Ví dụ:

 a = :print_something
b = :puts
alias :"#{a}" :"#{b}" 

Nhưng cách này trông xấu xí, nên bạn có thể muốn dùng alias_method cho tên phương thức động.

Phương thức alias_method

Tiếp theo:

Chúng ta có alias_method, một phương thức được định nghĩa trên Module.

Bạn chỉ có thể dùng phương thức này ở cấp độ class và module, không dùng bên trong instance method.

Mô tả từ tài liệu:

alias_method: "Làm cho new_name trở thành bản sao của phương thức old_name. Có thể dùng để giữ quyền truy cập vào các phương thức bị ghi đè."

Ví dụ:

 class Foo
  alias_method :print_something, :puts
end 

Điều này sẽ tạo bí danh print_something cho puts bên trong Foo.

Bạn có thể dùng string làm đối số cho alias_method.

Ví dụ:

 class Foo
  alias_method "print_something", "puts"
end 

alias vs alias_method

Bạn đã thấy tổng quan về alias và alias_method.

Nhưng khi nào sự khác biệt phát huy tác dụng?

  1. Khi định nghĩa bí danh cho tên phương thức được tạo động (như "abc#{rand}")
  2. Khi định nghĩa bí danh bên trong một phương thức

Việc tạo bí danh cho tên phương thức động có thể dùng từ khóa alias nhưng phải dùng symbol nội suy.

Với alias_method bạn có đối số linh hoạt hơn.

Ví dụ:

 class Cat
  def speak
    "meow"
  end
  alias_method "#{name.downcase}_speak", :speak
end
p Cat.new.cat_speak # "meow" 

Bây giờ:

Nếu bạn muốn định nghĩa bí danh bên trong một phương thức, bạn sẽ gặp lỗi:

 undefined method 'alias_method' for # (NoMethodError) 

Vì bạn đang làm việc trong một object chứ không phải class!

Bên trong instance method, bạn không có quyền truy cập các phương thức định nghĩa trong Module, nơi alias_method được định nghĩa.

Một giải pháp khả thi:

 def enable_aliased_methods
  self.class.send(:alias_method, :x, :testing)
end 

Sử dụng alias:

 def enable_aliased_methods
  alias :x :testing
end 

Một khác biệt quan trọng:

  • Phương thức do alias định nghĩa sẽ thuộc về class nơi alias được dùng
  • Phương thức do alias_method định nghĩa sẽ thuộc về self, class hiện tại tại thời điểm code chạy

Điều này quan trọng vì sao?

Nếu bạn gọi phương thức trên class cha dùng từ khóa alias…

Việc tạo bí danh sẽ xảy ra trên class cha chứ không phải class gọi phương thức.

Ví dụ:

 class Food
  def create_alias
    alias print_on_screen puts
  end
end
class Apple < Food
end
Apple.new.create_alias 

Nhưng nếu dùng alias_method, phương thức chỉ được tạo bí danh trên Apple.

Tạo bí danh tạo ra bản sao của phương thức

Theo mô tả của alias_method và alias, Ruby tạo ra một bản sao của phương thức.

Không chỉ là tên mới.

Mà là một bản sao thực sự của phương thức.

Điều này có một số ý nghĩa thực tế:

 def bacon
  123
end
alias :x :bacon
x # 123
bacon # 123 

Vậy chúng ta tạo bí danh x cho bacon, giờ xem gì xảy ra nếu định nghĩa lại bacon:

 def bacon
  234
end
x # 123
bacon # 234 

Phương thức x giữ nguyên, nhưng bacon trả về giá trị mới!

Điều này có thể gây bất ngờ nếu bạn include module vào class sau khi đã tạo bí danh phương thức.

Video hướng dẫn

Tóm tắt

Nói chung tôi thích alias_method hơn vì nó là một phương thức thực sự.

Trong khi từ khóa alias có một số đặc điểm đặc biệt phải nhớ và lưu ý.

Bạn có học được điều gì mới không?

Hãy chia sẻ bài viết này với bạn bè lập trình Ruby để họ cũng học được!