2010-03-04 32 views
15

Tôi đang cố gắng viết một phương thức hoạt động như một bộ đặt và nhận một số đối số thừa bên cạnh giá trị được gán. Silly dụ:Tạo phương thức setter có thêm đối số trong Ruby

class WordGenerator 
    def []=(letter, position, allowed) 
    puts "#{letter}#{allowed ? ' now' : ' no longer'} allowed at #{position}" 
    end 

    def allow=(letter, position, allowed) 
    # ... 
    end 
end 

Viết nó như một tác phẩm indexer và tôi có thể gọi nó như thế này:

gen = WordGenerator.new 

gen['a', 1] = true 
# or explicitly: 
gen.[]=('a', 1, true) 

Nhưng khi tôi thử bất kỳ những điều sau đây, các thông dịch viên phàn nàn:

gen.allow('a', 1) = false # syntax error 
gen.allow=('a', 1, false) # syntax error 

Tại sao điều này không hoạt động, tôi có thiếu hiển nhiên không?

+0

liên quan/trùng lặp: http://stackoverflow.com/questions/9280623/setter-method-assignment-with-multiple-arguments – kotique

Trả lời

16

Nó không hoạt động vì trình phân tích cú pháp không cho phép. Dấu bằng được cho phép trong biểu thức của biểu mẫu identifier = expression, expression.identifier = expression (trong đó số nhận dạng là \w+), expression[arguments] = expressionexpression.[]= arguments và như một phần của chuỗi hoặc ký hiệu hoặc ký tự chữ (?=). Đó là nó.

gen.send(:allow=, 'a', 1, false) sẽ hoạt động, nhưng tại thời điểm đó bạn cũng có thể chỉ cung cấp cho phương thức tên không bao gồm =.

+0

Cảm ơn. Điều thú vị là nó cho phép các công cụ như 'def seed = (giá trị) kết thúc; gen.seed = (1) '. Tôi đã mong đợi 'seed =' là số nhận dạng, nhưng (nếu tôi hiểu quy tắc của bạn một cách chính xác), nó sẽ giống như: [gen/expr]. [Seed/identifier] = [(1)/expr]. Điều này sẽ giải thích tại sao nó thất bại với nhiều hơn một đối số - (a) là một biểu thức, tuy nhiên (a, b) là không! Giả sử lưu giữ này, tác phẩm 'gen. [] = (' A ', 1, true)' hoạt động như thế nào? –

+0

'. [] =' Là một trường hợp đặc biệt khác mà tôi đã quên trong danh sách ở trên (cùng với 'biểu thức [comma_seperated_expressions] = expression', tất nhiên cũng hoạt động). – sepp2k

6

Tôi đã bắt gặp điều này và quyết định chuyển đối số của tôi dưới dạng mảng hoặc băm.

ví dụ .:

def allow=(arguments) 
    puts arguments[:letter] 
    puts arguments[:position] 
    puts arguments[:allowed] 
end 

object.allow={:letter=>'A',:position=>3,:allowed=>true} 
Các vấn đề liên quan