2015-08-08 20 views
7

Giả sử rằng tôi có một đối tượng, x, có thể chấp nhận bất kỳ bộ chọn nào, s1, s2, ..., sn. Hãy giả sử thêm rằng kết quả của bất kỳ bộ chọn nào trong số các bộ chọn này hoạt động trên đối tượng là đối tượng được cập nhật cùng loại. Tôi có thể sau đó "chuỗi" những selectors (miễn là họ điệp unary) như tôi muốn, chẳng hạn như:Chaining tin nhắn từ khóa

x s1 s2 ... sn 

này sẽ đưa kết quả của x s1 và áp dụng selector s2, sau đó áp dụng selector s3 để kết quả đó, v.v. Tôi muốn áp dụng một hoặc nhiều bộ chọn này theo một số thứ tự cho các kết quả khác nhau:

x s8 s2 

Trong Smalltalk tôi có thể làm điều này nếu bộ chọn là thông điệp đơn nhất. Tuy nhiên, nếu các công cụ chọn của tôi là tin nhắn từ khóa, tôi không thể thực hiện việc này nữa. Nếu x cá nhân chấp nhận selectors, s1:, s2: ..., sn:, thì sau đây không làm việc:

x s1: a1 s2: a2 ... sn: an 

Có là ; điều hành:

x s1: a1 ; s2: a2 ; ... ; sn: an 

Nhưng sử dụng tầng : mỗi giai đoạn sửa đổi bản gốc x trên đường đi và tôi không muốn sửa đổi x trong trường hợp này.

Để thông điệp từ khóa dây chuyền, tôi nghĩ rằng tôi trái bằng cách sử dụng cú pháp sau với dấu ngoặc đơn:

(...(((x s1: a1) s2: a2) ... sn: an) 

nào khiến tôi cảm thấy như tôi là lập trình trong LISP nếu tôi có 3 hoặc nhiều tin nhắn keywrod. Một ví dụ cụ thể về điều này có thể là một mảng đa chiều. Nếu foo là một mảng 3 chiều, và bạn muốn truy cập vào một đối tượng ở vị trí 2,3,5 trong mảng, tôi nghĩ rằng nó sẽ trông giống như:

(((foo at: 2) at: 3) at: 5) some_object_selectors 

Đó là một ví dụ nhỏ, tất nhiên, nhưng minh họa trường hợp. Người ta có thể có các loại đối tượng nhúng khác hoặc chuỗi các hoạt động đối tượng liên tiếp khác mà bạn quan tâm đến kết quả cuối cùng.

Có cách nào hấp dẫn hơn để thực hiện điều này trong Smalltalk không? Tôi giả không có một nhà điều hành, có lẽ anh em họ đến các nhà điều hành ; (nói chúng tôi sử dụng & ví dụ), trong đó sẽ chuỗi chúng, chẳng hạn như:

x s1: a1 & s2: a2 & ... & sn: an 

Vì tôi muốn áp dụng các selectors trong bất kỳ hoặc gần như bất kỳ thứ tự mong muốn nào (đối với các kết quả có thể khác nhau), biểu mẫu chọn, s1:s2:s3:... quá hạn chế. Ngoài ra, điều này mang lại một cơ sở mà đã tồn tại trong các ngôn ngữ khác, chẳng hạn như Ruby, nơi nó sẽ được tương đương biểu diễn như:

x.s1(a1).s2(a2)...sn(an) 

Thiếu một nhà điều hành đặc biệt, một sự thay thế có thể là để vượt qua một loạt các cặp chọn đối số hoặc có thể là bảng tra cứu các cặp đối số chọn.Bảng tra cứu đòi hỏi thiết lập để thông qua literals (nó phải được tạo ra và dân cư), mà làm cho tôi nghiêng về một mảng kể từ khi tôi chỉ có thể viết nó như:

x { {s1. a1}. {s2. a2}. ... {sn. an} } 

này vẫn còn một chút thời gian, và tôi m không phải như vậy chắc chắn đây là bất kỳ thanh lịch hơn so với chỉ sử dụng tất cả các dấu ngoặc đơn. Tôi sợ câu hỏi của tôi có thể ít nhất là một phần chủ quan, nhưng tôi quan tâm biết thực hành tốt nhất có thể là gì và liệu một nhà điều hành có tồn tại hay không. tiêu chuẩn cơ thể.

+0

Câu hỏi hay, đôi khi được thể hiện dưới dạng đường ống thông báo hoặc đường ống - bạn không phải là người đầu tiên bỏ lỡ tính năng đó, nó thường xuyên được thảo luận trong danh sách gửi thư. Tôi khuyên bạn nên viết blog exbent http://blog.3plus4.org/2007/08/30/message-chains/ –

+0

@ aka.nice vâng, có vẻ như họ đã đánh tôi với câu hỏi 8 năm trước. :) – lurker

Trả lời

1

Thông thường, chúng tôi cung cấp cho đối tượng này x đối tượng để vận hành và sau đó yêu cầu đối tượng đã thay đổi này khi chúng tôi kết thúc. Sao chép là khá kém hiệu quả.

Object subclass: #Foo 
    instanceVariableNames: 'subject' 
    classVariableNames: '' 
    poolDictionaries: '' 
    category: 'Try' 

order: y 
    self subject order: y 

select: z 
    self subject select: z 

subject 
    ^subject ifNil: [ subject := FooSubject new ] 

where: x 
    self subject where: x 
+0

Tôi hiểu. Tôi đã tìm kiếm một cách để có được hiệu ứng tương tự như x.s1 (a1) .s2 (a2) ... sn (an) như được thực hiện trong Ruby, ví dụ, mà không cần phải nghỉ mát cho tất cả các dấu ngoặc đơn. Đối tượng x là một cái gì đó tôi có thể muốn áp dụng các hoạt động khác nhau vào các thời điểm khác nhau với các bộ chọn khác nhau. Vì vậy, tôi không muốn thay đổi nó. Nếu nó thay đổi, sau đó tôi phải tạo bản sao của nó trong trường hợp đó vì vậy tôi có nó ở dạng ban đầu của nó một lần nữa.Nếu tôi muốn lưu một đối tượng có một số hoạt động được thực hiện trên nó, tôi sẽ làm điều đó bằng, 'newX: = x s1: a1 | s3: a3.' chẳng hạn. – lurker

+0

Bạn đang cố gắng đạt được điều gì? Tôi không chắc làm thế nào để viết mã dễ hiểu với cấu trúc đó. –

+0

Loại cấu trúc này được sử dụng phổ biến trong Ruby on Rails. Khi xây dựng các truy vấn với 'ActiveRecord', người ta có thể làm những việc như,' Foo.where (...). Order (...). Select (...) 'nhưng' Foo' không thay đổi. Ngữ nghĩa của đoạn mã khá rõ ràng. Có lẽ trong trường hợp này, trong mô hình Smalltalk, tôi chỉ cần tạo một bản sao của 'Foo' mỗi lần và để các nhà khai thác sửa đổi nó. Tôi sẽ phải suy nghĩ một chút. – lurker

8

Dường như có sự nhầm lẫn nào đó ở đây.

  1. Cascading được thực hiện sử dụng ;, nơi mỗi tin nhắn được gửi đến lập luận tương tự.
  2. Ví dụ x s1 s2... của bạn được gọi là chuỗi tin nhắn, trong đó mỗi thư được gửi đến kết quả của thư trước đó (do bản chất đẹp và thanh lịch của cú pháp Smalltalk, đơn giản là Object message và luôn trả về kết quả). Và không, bạn không thể luôn đặt chúng theo bất kỳ thứ tự nào. Hãy tưởng tượng s1multiplyByTwos2addTwo, với x có biến mẫu được sửa đổi theo các phương pháp bắt đầu là 1. Đặt hàng có thể quan trọng. (Xin lưu ý rằng tôi rất miễn cưỡng sử dụng những tên ngắn khủng khiếp đó làm ví dụ - nó không giống như Smalltalk. ;-)
  3. Nếu số n của bạn quá lớn nên việc sử dụng dấu ngoặc đơn làm cho nó trông khó xử, sau đó, uhm .. xin lỗi, nhưng bạn đang làm sai.
    • Cân nhắc tạo phương thức trên đối tượng của bạn để chấp nhận nhiều đối số.
    • Cân nhắc tạo đối tượng bao bọc để thực hiện các thông số của bạn.
    • Cân nhắc sử dụng mẫu thiết kế để tách đối tượng khỏi các thao tác bạn muốn thực hiện trên đó. (Những mô hình bạn cần sẽ phụ thuộc vào những gì bạn muốn đạt được;. here's a good starting point)

Thay vì tìm kiếm một nhà điều hành để uốn cong Smalltalk ý muốn của bạn (về cách bạn có thể được sử dụng để làm việc trong khác ngôn ngữ), tôi khuyên bạn nên uốn cong để Smalltalk sẽ thay thế (rõ ràng đặt tên, không sợ tạo ra nhiều đối tượng và phương pháp, vv). Bạn sẽ nhận được nhiều hơn về nó trong thời gian dài, và tôi dám nói rằng bạn sẽ nhận được đến mức mà bạn muốn ngôn ngữ khác có sự đơn giản và sức mạnh của Smalltalk.

+0

Cảm ơn bạn đã nhập. Tôi xin lỗi tôi đã sai thuật ngữ. Gần đây tôi đã bắt đầu học ST, và đã quên mất sự khác biệt về thuật ngữ. Theo chiều rộng của 'n', kích thước của nó quá lớn? Tôi nghĩ rằng nếu nó là 4 hoặc 5 nó trông xấu xí. Nhưng đó là chủ quan. Chắc chắn tôi đang cố gắng hiểu triết lý ngôn ngữ tốt hơn, và đã đọc rất nhiều về nó. Tôi không nhất thiết phải "cố gắng uốn cong nó theo ý muốn của tôi" nhưng tìm kiếm sự hiểu biết. Đối với tôi (một chuyển đổi gần đây thành ST), khả năng * chuỗi * chỉ những bộ chọn không có đối số dường như không phù hợp với tôi. – lurker

+0

Tôi nhận ra rằng tôi không thể luôn đặt tin nhắn theo thứ tự mà tôi muốn. Tôi đã nói về một vấn đề trong đó, trong trường hợp của tôi, tôi đã * muốn làm như vậy. Vì vậy, tôi không thể coi nó là 's1: s2: s3: ...' để buộc thứ tự. Cảm ơn bạn đã cung cấp liên kết, tôi sẽ đọc nó. – lurker

+0

Không cần phải xin lỗi, chỉ nghĩ rằng tôi sẽ làm rõ, bởi vì tôi đã bối rối khi lần đầu tiên đọc qua câu hỏi. Và tất nhiên bạn đúng về nó là chủ quan. Tôi chỉ thấy rằng những người đến Smalltalk từ các ngôn ngữ khác có xu hướng miễn cưỡng hơn để tạo ra các đối tượng và phương thức mới (nhỏ). Đủ công bằng về thứ tự tin nhắn, cảm ơn vì đã giải thích. Nghe có vẻ như bạn có thể sau một mẫu, sau đó. Kudos vì đã cố gắng để _get_ Smalltalk! :-) –

Các vấn đề liên quan