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

Làm chủ Hằng số Ruby: Định nghĩa, Sử dụng và Thực hành Tốt nhất

Hằng số trong Ruby là gì?

Hằng số là một loại biến luôn bắt đầu bằng chữ cái in hoa. Chúng chỉ có thể được định nghĩa ngoài phương thức, trừ khi bạn dùng metaprogramming.

Hằng số được dùng cho các giá trị không nên thay đổi, nhưng Ruby không ngăn bạn thay đổi chúng.

Chúng trông như thế này:

FRUIT = "orange"

Bây giờ:

Vì hằng số là chủ đề quan trọng, chúng ta sẽ khám phá chi tiết trong bài viết này!

Cách Định nghĩa Hằng số

Hằng số không yêu cầu bất kỳ ký hiệu hoặc cú pháp đặc biệt nào để khai báo. Bạn chỉ cần làm cho chữ cái đầu tiên thành chữ in hoa.

Dưới đây là các hằng số hợp lệ:

ABC = 1 Goo = 2 Foo = 3

Lưu ý rằng bạn không thể định nghĩa hằng số bên trong phương thức.

Bạn sẽ nhận được thông báo lỗi bí ẩn này:

def the_method ABC = 1 end # "dynamic constant assignment"

Vì vậy, hãy định nghĩa hằng số của bạn bên ngoài phương thức, thường chúng ta muốn định nghĩa hằng số ở đầu lớp để chúng rõ ràng.

class RubyBlog URL = "rubyguides.com" AUTHOR = "Jesus Castello" end

Sau đó bạn có thể truy cập các hằng số này bên trong phương thức lớp hoặc bên ngoài lớp bằng cú pháp sau:

p RubyBlog::AUTHOR # "Jesus Castello"

Chúng ta sẽ nói thêm về phạm vi của hằng số sau trong bài viết này, vì vậy hãy tiếp tục theo dõi!

Lỗi Hằng số Chưa Khởi tạo

Một lỗi phổ biến bạn có thể gặp là:

puts Foo # "uninitialized constant Foo (NameError)"

Tôi muốn bạn chuyển dịch lỗi này trong tâm trí thành "hằng số không tìm thấy".

Một điểm quan trọng để hiểu lỗi này là các lớp Ruby là hằng số.

Ví dụ:

Array String Hash

Chúng là hằng số vì chữ cái đầu tiên in hoa.

Khi bạn định nghĩa một lớp, những gì bạn thực sự làm là tạo một đối tượng Class, được gán cho một hằng số.

Hằng số trở thành tên lớp.

Tại sao điều này quan trọng?

Bởi vì lý do khả năng cao nhất bạn thấy lỗi "uninitialized constant" là bạn quên require tệp hoặc gem định nghĩa hằng số.

Hoặc có thể bạn chỉ gõ sai tên hằng số.

Vì vậy hãy để ý điều đó.

Hằng số Có Thể Thay Đổi

Như tôi đã nói trong phần giới thiệu, hằng số Ruby có thể thay đổi.

Ví dụ:

ABC = 1 ABC = 2

Nhưng bạn sẽ thấy thông báo cảnh báo này:

2: warning: already initialized constant ABC

Chương trình của bạn vẫn hoạt động tốt, nhưng bạn muốn tránh điều này.

Không có cách nào ngăn hằng số thay đổi vì biến trong Ruby không phải là container, chúng chỉ đơn giản là con trỏ đến đối tượng.

Hoặc nhãn, nếu bạn thích.

Điều tốt nhất bạn có thể làm là dùng đối tượng bất biến.

Ví dụ:

AUTHOR = "Jesus Castello".freeze AUTHOR << "o" # RuntimeError: can't modify frozen String

Bài viết liên quan: Tính bất biến của Ruby & phương thức freeze.

Trong ví dụ này, bạn vẫn có thể thay đổi thứ AUTHOR trỏ tới, chỉ có freeze bảo vệ bạn khỏi việc thay đổi chính đối tượng đó.

Phương thức Hằng số

Có một vài phương thức dành riêng cho làm việc với hằng số:

Phương thức Mô tả
constants Trả về mảng các symbol đại diện cho hằng số được định nghĩa trong một lớp
const_get Trả về giá trị cho một hằng số. Nhận symbol hoặc string làm tham số
const_set Đặt giá trị cho một hằng số. Nhận hai tham số: tên hằng số dạng symbol & giá trị hằng số
const_missing Tương tự method_missing nhưng cho hằng số
const_defined? Trả về true nếu một hằng số cho trước (dạng symbol) đã được định nghĩa
remove_const Xóa một hằng số
private_constant Làm cho hằng số thành private nên không thể truy cập bên ngoài lớp với cú pháp Class::ABC

Có một vài thủ thuật metaprogramming bạn có thể làm với các phương thức này.

Ví dụ:

module Food class Bacon; end class Chocolate; end end puts "Classes defined inside #{Food}:" puts Food.constants

Cũng có thể dùng string như "Array" và lấy lớp thực tế:

array_class = Object.const_get("Array")

Nhưng hãy cẩn thận với cái đó vì người dùng có thể tiêm mã nếu string đến từ params hoặc hình thức nhập liệu người dùng khác.

Trong Rails, có phương thức constantize về cơ bản làm const_get cho bạn, nhưng hãy nhớ rằng nó không làm bất kỳ kiểm tra bảo mật nào.

CheatSheet

Làm chủ Hằng số Ruby: Định nghĩa, Sử dụng và Thực hành Tốt nhất

Phạm vi Hằng số Ruby

Khi bạn tạo hằng số bên ngoài bất kỳ lớp nào, ở cấp độ cao nhất của mã, hằng số đó sẽ có sẵn khắp mọi nơi.

Hằng số cũng có sẵn trong các lớp con.

class A FOO = 1 end class B < A def foo puts FOO end end B.constants # [:FOO]

Hằng số được định nghĩa bên ngoài module hoặc lớp lồng nhau cũng có sẵn bên trong các lớp lồng nhau.

module Food STORE_ADDRESS = "The moon" class Bacon def foo; puts STORE_ADDRESS; end end end fb = Food::Bacon.new fb.foo # "The moon"

Trộn Module

Hằng số từ module được include cũng có sẵn:

module Mixin A = 123 end class Product include Mixin puts A end # 123

Lưu ý rằng điều này hoạt động khi include module, nó sẽ không hoạt động nếu bạn extend nó.

Ví dụ:

class Product extend Mixin puts A end # uninitialized constant Product::A

Cũng:

Khi bạn dùng phương thức đã được include từ module, Ruby sẽ tìm hằng số bắt đầu từ nơi phương thức đó được định nghĩa.

Ví dụ:

module Parent def print_value VALUE end end class Child include Parent VALUE = 1 end # Works p Child::VALUE # uninitialized constant Parent::VALUE p Child.new.print_value

Điều cần nhớ!

Lồng Module

Tôi muốn cho bạn thấy thêm một ví dụ với các lớp lồng nhau (tương tự cho module).

class A FOO = 1 end class A::B class C puts FOO end end

Lưu ý ký hiệu A::B ở đây, chúng ta thử dùng như một lối tắt. Nhưng vấn đề là lớp C sẽ không có quyền truy cập trực tiếp vào FOO.

Vì lý do đó, bạn muốn dính vào loại lồng nhau này:

class A FOO = 1 end class A class B class C puts FOO end end end

Trong ví dụ đầu tiên, bạn vẫn có thể làm ::A::FOO để truy cập hằng số, nhưng nếu tên lớp thay đổi thì bạn sẽ gặp lỗi.

Cú pháp ::A::FOO này hoạt động vì nó bảo Ruby tìm trong phạm vi cấp cao nhất, nơi các hằng số như Array và String được định nghĩa.

Video

Tóm tắt

Bạn đã học về hằng số Ruby, một loại biến có hành vi thú vị. Bạn có thể thay đổi giá trị hằng số nhưng nó sẽ in cảnh báo.

Bạn cũng học được rằng tên lớp là hằng số và bạn nên tránh const_get với đầu vào người dùng.

Nếu bạn thích bài viết này đừng quên chia sẻ để nhiều người hơn hiểu cách hằng số hoạt động.