Tại sao nội suy chuỗi hoạt động trong Ruby khi không có dấu ngoặc nhọn?


90

Cách thích hợp để sử dụng nội suy chuỗi trong Ruby như sau:

name = "Ned Stark"
puts "Hello there, #{name}" #=> "Hello there, Ned Stark"

Đó là cách tôi dự định sẽ luôn sử dụng nó.

Tuy nhiên, tôi đã nhận thấy điều gì đó kỳ lạ trong nội suy chuỗi của Ruby. Tôi nhận thấy rằng nội suy chuỗi hoạt động trong Ruby mà không có dấu ngoặc nhọn liên quan đến các biến cá thể. Ví dụ:

@name = "Ned Stark"
puts "Hello there, #@name" #=> "Hello there, Ned Stark"

Và việc thử tương tự như một biến không phải là phiên bản sẽ không hoạt động.

name = "Ned Stark"
puts "Hello, there, #name" #=> "Hello there, #name"

Tôi đã thử điều này thành công trong cả 1.9.2 và 1.8.7.

Tại sao điều này hoạt động? Thông dịch viên đang làm gì ở đây?

Câu trả lời:


103

Theo Ngôn ngữ lập trình Ruby của Flanagan và Matsumoto:

Khi biểu thức được nội suy vào chuỗi ký tự chỉ đơn giản là một tham chiếu đến một biến toàn cục, cá thể hoặc lớp, thì dấu ngoặc nhọn có thể bị bỏ qua.

Vì vậy, tất cả những điều sau đây sẽ hoạt động:

@var = "Hi"
puts "#@var there!"  #=> "Hi there!"

@@var = "Hi"
puts "#@@var there!" #=> "Hi there!"

$var = "Hi"
puts "#$var there!"  #=> "Hi there!"

4
Câu hỏi thú vị, btw. Thật tuyệt khi quay lại và tìm lại những góc nhỏ của ngôn ngữ mà tôi đã quên mất.
tsherif

2
Mặc dù câu trả lời của bạn không chứa lý do tại sao hoặc điều gì đang xảy ra, nhưng tôi thấy rằng lý do đó thật khó xác định. Ngay cả những bảng tin cũ mà Matz thường xuyên bình luận cũng không giúp được gì. Tuy nhiên, câu trả lời của bạn cho thấy đó là một tính năng trái ngược với chỉ là một trò may rủi.
Charles Caldwell

1
Tôi không chắc bạn đang mong đợi điều gì như một lý do. Ý bạn là một quyết định thiết kế? Tôi đoán rằng đó là một nỗ lực với cú pháp giống Perl , vì tôi tin rằng Ruby ban đầu được hình thành như một loại Perl ++ trước khi trở thành của riêng nó.
tsherif

2
Tôi là một noob hoàn toàn và vừa có IDE của tôi phàn nàn về việc tôi làm điều này. Nhưng tôi đang gặp khó khăn khi thuyết phục bản thân rằng đó là phong cách tốt. Nó hoàn toàn không nhất quán và có một nhược điểm - ví dụ: nếu tôi có một biến cá thể @distance với giá trị 100 và muốn tạo một chuỗi có nội dung như "100m" bằng cách sử dụng biểu thức như "# @ distancem", tôi sẽ chỉ nhận được một chuỗi trống bởi vì không có biến instance 'distancem'. Vì vậy, điều này nghe có vẻ như phong cách hoàn toàn tồi tệ.
terriblememory

3
@terriblememory Ồ chắc chắn là phong cách tồi. Đó là lý do tại sao tôi bắt đầu câu hỏi của mình bằng cách chỉ ra cách làm đúng. Tuy nhiên, tôi chỉ thấy kỳ lạ khi nó là một tính năng của ngôn ngữ và tự hỏi tại sao nó hoạt động. Sau đó, một lần nữa, nó cũng là một phong cách xấu khi bắt đầu một câu với một kết hợp. Nhưng bạn vẫn sẽ thấy mọi người sử dụng nó ở đây và ở đó. =)
Charles Caldwell
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.