Vậy, tại sao những người sáng tạo Ruby phải sử dụng khái niệm về symbols
ngôn ngữ?
Chà, họ không nghiêm túc "phải", họ đã chọn. Ngoài ra, lưu ý rằng nói đúng Symbol
không phải là một phần của ngôn ngữ, chúng là một phần của thư viện cốt lõi. Họ làm có cú pháp văn chương ngôn ngữ cấp, nhưng họ sẽ chỉ làm việc tốt nếu bạn có để xây dựng chúng bằng cách gọi Symbol::new
.
Tôi hỏi từ quan điểm của một lập trình viên không phải là ruby đang cố gắng hiểu nó. Tôi đã học được rất nhiều ngôn ngữ khác và thấy không có ngôn ngữ nào trong số chúng cần phải xác định xem tôi có giao dịch hay không với những gì Ruby gọi symbols
.
Bạn đã không nói "rất nhiều ngôn ngữ khác" là gì, nhưng đây chỉ là một đoạn trích nhỏ về các ngôn ngữ có Symbol
kiểu dữ liệu như của Ruby:
- Bản thảo , cũng là JavaScript
- Scala
- Scheme , Common Lisp , Clojure (cũng vậy, Clojure có từ khóa ), về cơ bản là mọi ngôn ngữ trong gia đình Lisp, những người kế thừa và anh em họ đều có chúng
- Smalltalk , Drameak và nhiều ngôn ngữ khác trong gia đình Smalltalk (có khả năng Ruby lấy chúng từ đó), bao gồm cả Objective-C (mặc dù ở dạng hạn chế)
- Erlang (được gọi là nguyên tử ) , cũng là Elixir và LFE
- Julia
- Prolog (được gọi là nguyên tử ), có khả năng Erlang đã lấy chúng từ
Ngoài ra còn có các ngôn ngữ khác cung cấp các tính năng của Symbol
s ở dạng khác. Ví dụ, trong Java, các tính năng của Ruby String
được chia thành hai loại (thực tế là ba): String
và StringBuilder
/ StringBuffer
. Mặt khác, các tính năng của loại Ruby Symbol
được xếp lại thành String
loại Java : Java String
có thể được thực hiện , các chuỗi ký tự và String
s là kết quả của các biểu thức hằng số được đánh giá theo thời gian biên dịch được tự động thực hiện, String
có thể được tạo động bằng cách gọi các String.intern
phương pháp. Một thực tập sinh String
trong Java giống hệt như Symbol
trong Ruby, nhưng nó không được triển khai như một loại riêng biệt, nó chỉ là một trạng thái khác với JavaString
có thể có. (Lưu ý: trong các phiên bản trước của Ruby, String#to_sym
được gọi làString#intern
và phương pháp đó vẫn tồn tại cho đến ngày nay như một bí danh kế thừa.)
Câu hỏi chính có thể là: Liệu khái niệm về symbols
Ruby có tồn tại như một mục đích hiệu suất đối với chính nó và các ngôn ngữ khác,
Symbol
s là đầu tiên và quan trọng nhất là một kiểu dữ liệu với ngữ nghĩa cụ thể . Các ngữ nghĩa này cũng cho phép thực hiện một số thao tác thực hiện (ví dụ: kiểm tra đẳng thức nhanh O (1)), nhưng đó không phải là mục đích chính.
hoặc chỉ một cái gì đó là cần thiết để tồn tại vì cách viết ngôn ngữ?
Symbol
Không cần thiết trong ngôn ngữ Ruby, Ruby sẽ hoạt động tốt nếu không có chúng. Chúng hoàn toàn là một tính năng của thư viện. Có chính xác một vị trí trong ngôn ngữ được gắn với Symbol
s: một def
biểu thức định nghĩa phương thức ước tính thành một Symbol
biểu thị tên của phương thức đang được định nghĩa. Tuy nhiên, đó là một thay đổi khá gần đây, trước đó, giá trị trả về chỉ đơn giản là không xác định. MRI chỉ đơn giản là đánh giá nil
, Rubinius đã đánh giá một Rubinius::CompiledMethod
đối tượng, v.v. Cũng có thể đánh giá một điểm UnboundMethod
hay chỉ là a String
.
Liệu một chương trình trong Ruby sẽ nhẹ hơn và / hoặc nhanh hơn chương trình của nó, giả sử, đối tác Python hoặc Node? Nếu vậy, nó sẽ là vì symbols
?
Tôi không chắc chắn những gì bạn đang hỏi ở đây. Hiệu suất chủ yếu là vấn đề chất lượng thực hiện, không phải ngôn ngữ. Thêm vào đó, Node thậm chí không phải là một ngôn ngữ, đó là khung I / O được tổ chức cho ECMAScript. Chạy một kịch bản tương đương trên IronPython và MRI, IronPython có thể sẽ nhanh hơn. Chạy một kịch bản tương đương trên CPython và JRuby + Truffle, JRuby + Truffle có thể sẽ nhanh hơn. Điều này không liên quan gì đến Symbol
s nhưng với chất lượng thực hiện: JRuby + Truffle có trình biên dịch tối ưu hóa mạnh mẽ, cộng với toàn bộ máy móc tối ưu hóa của JVM hiệu suất cao, CPython là một trình thông dịch đơn giản.
Vì một trong những mục đích của Ruby là dễ đọc và viết cho con người, nên những người tạo ra nó không thể làm dịu quá trình mã hóa bằng cách thực hiện những cải tiến đó trong chính trình thông dịch (như có thể bằng các ngôn ngữ khác)?
Số Symbol
s không phải là một tối ưu hóa trình biên dịch. Chúng là một kiểu dữ liệu riêng biệt với ngữ nghĩa cụ thể. Chúng không giống như các bản sao của YARV , đó là một tối ưu hóa nội bộ riêng tư cho Float
s. Tình huống này không giống như đối với Integer
, Bignum
và Fixnum
, đáng lẽ là một chi tiết tối ưu hóa nội bộ riêng tư vô hình, nhưng thật không may. (Điều này cuối cùng sẽ được sửa trong Ruby 2.4, nó sẽ loại bỏ Fixnum
và Bignum
chỉ để lại Integer
.)
Làm theo cách mà Java thực hiện, như một trạng thái đặc biệt của String
s bình thường có nghĩa là bạn luôn cần phải cảnh giác về việc liệu bạn String
có ở trạng thái đặc biệt đó hay không và trong trường hợp nào chúng sẽ tự động ở trạng thái đặc biệt đó và khi nào thì không. Đó là một gánh nặng cao hơn nhiều so với việc chỉ có một kiểu dữ liệu riêng biệt.
Sẽ có một định nghĩa ngôn ngữ bất khả tri về các Biểu tượng và một lý do để có chúng trong các ngôn ngữ khác?
Symbol
là một kiểu dữ liệu biểu thị khái niệm tên hoặc nhãn . Symbol
s là các đối tượng giá trị , không thay đổi, thường là ngay lập tức (nếu ngôn ngữ phân biệt một thứ như vậy), không trạng thái và không có danh tính. Hai Symbol
s bằng nhau cũng được đảm bảo giống hệt nhau, nói cách khác, hai Symbol
s bằng nhau thực sự là một Symbol
. Điều này có nghĩa là bình đẳng giá trị và đẳng thức tham chiếu là như nhau, và do đó, đẳng thức là hiệu quả và O (1).
Những lý do để có chúng trong một ngôn ngữ là thực sự giống nhau, độc lập với ngôn ngữ. Một số ngôn ngữ dựa nhiều vào chúng hơn những ngôn ngữ khác.
Trong gia đình Lisp, chẳng hạn, không có khái niệm "biến". Thay vào đó, bạn có Symbol
liên quan đến các giá trị.
Trong các ngôn ngữ với khả năng phản xạ hay nội tâm, Symbol
s thường được sử dụng để biểu thị tên của các đơn vị phản ánh trong các API phản chiếu, ví dụ như trong Ruby, Object#methods
, Object#singleton_methods
, Object#public_methods
, Object#protected_methods
, và Object#public_methods
trả về một Array
của Symbol
s (mặc dù họ có thể chỉ cần cũng trả về một Array
trong Method
s). Object#public_send
lấy một Symbol
ký hiệu tên của tin nhắn để gửi làm đối số (mặc dù nó cũng chấp nhận String
như vậy, nhưng Symbol
đúng hơn về mặt ngữ nghĩa).
Trong ECMAScript, Symbol
s là một khối xây dựng cơ bản để làm cho khả năng ECMAScript an toàn trong tương lai. Họ cũng đóng một vai trò lớn trong sự phản ánh.