2013-08-21 31 views
5

Thay vì tạo đối tượng bằng cách viết:khối Interleave, hoặc làm cho đối tượng ra khỏi hai khối (tên trường và giá trị)

obj: object [ 
    name: "Fork" 
    id: 1020 
] 

Tôi muốn viết một cái gì đó giống như ...

obj: something-or-another [name id] ["Fork" 1020] 

... và nhận được kết quả tương tự. Một giải pháp lý tưởng cũng sẽ cho phép:

obj: something-or-another [name: id:] ["Fork" 1020] 

đủ dễ dàng để viết một something-or-another, nhưng không phù hợp với một cái gì đó này đã "trong hộp"?

Trả lời

3

Tôi không tin có cách nào để làm điều này. Không khó khăn mặc dù:

func [words values][ 
    set words: context append map-each word words [to set-word! word] none values 
    words 
] 

Tôi cho rằng tôi có thể phá vỡ này xuống một chút:

func [ 
    "Creates an Object From a Block of Words, Assigns Values" 
    words [block!] "Words used to create object" 
    values "Value(s) to assign" 
][ 
    words: map-each word words [to set-word! word] ; The requisite set-words 
    append words none ; Initial value for all words 
    words: context words ; Create our object 
    set words values ; Assigns our value(s) to the object 
    words ; returns the object 
] 

Bạn có thể sử dụng một phương pháp khác nhau để interleave khối, chẳng hạn như:

func [words [block!] values [block!]][ 
    collect [ 
     repeat index max length? words length? values [ 
      keep words/:index 
      keep values/:index 
     ] 
    ] 
] 
+0

Ví dụ đầu tiên về mã của bạn (chức năng có thể cần tên) ngắn và rõ ràng và có vẻ như là tốt nhất đối với tôi. – Ladislav

1

tôi đã viết chức năng tương tự (Rebol2) chỉ cách đây vài ngày:

build-object: func [ 
    "Builds an object from a block" 
    names [block!] "Field names" 
    /values val [block!] "Initial values" 
    /local o name value 
] [ 
    o: copy [] 
    names: compose names 
    o: either values [ 
     parse names [ 
      some [ 
       set name [word! | set-word!] 
       (append o to-set-word name) 
       | skip 
      ] 
     ] 
     set/pad reflect o: context append o none 'words val 
     o 
    ] [ 
     if any [ 
      parse names [ 
       some [ 
        set name [word! | set-word!] 
        (append o reduce [to-set-word name none]) 
       ] 
      ] 
      parse names [ 
       (clear o) some [ 
        set name [word! | set-word!] set value any-type! 
        (append o reduce [to-set-word name :value]) 
       ] 
      ] 
     ] [context o] 
    ] 
    o 
] 

Xây dựng đối tượng của bạn, bạn có thể viết bất kỳ: (tạo một hàm như f: does ["x"])

  • build-object [name "Fork" id 1020]
  • build-object [name: "Fork" id: 1020]
  • build-object/values [name id] ["Fork" 1020]
  • build-object/values [name: id:] ["Fork" 1020]
  • build-object [name f]
  • build-object [name (f)] ;block is composed
  • build-object [name 5 id f]
  • build-object [name 5 id 'f]

Bạn cũng có thể làm cho đối tượng với các lĩnh vực thiết lập để none nếu bạn để lại các giá trị ra ngoài, ví dụ với

build-object [name id] 
+0

Thú vị rằng nó sẽ xuất hiện nhiều lần trong một thời gian ngắn! Có thể một dấu hiệu cho thấy nó thường xuất hiện, và một cái gì đó ở đây cần được chuẩn hóa.Có lý do nào để diễn đạt 'quy tắc-giá trị' của bạn giống như trái ngược với một' khác biệt' từ 'bất kỳ kiểu nào!'? – HostileFork

+0

Đó là nhu cầu đặc biệt của tôi. Nhưng bạn nói đúng, sử dụng bất kỳ loại nào! có thể hữu ích. – endo64

+0

Tôi đã viết một phiên bản khác bằng cách sử dụng bất kỳ loại nào và một số bản sửa lỗi nhỏ, tôi có nên chỉnh sửa câu trả lời trước đó của mình hoặc thêm câu trả lời mới không? – endo64

2

Đây là cái gì mà đòi hỏi phải có ít nhất Rebol 3:

func [ 
    "Create an object based on some words and values." 
    words [any-word! block!] "Word or block of words" 
    values [any-type!] "Value or block of values" 
    /local object 
][ 
    object: make object! either block? words [length? words] [1] 
    set bind/copy/new :words object :values 
    object 
] 

Nếu bạn cũng muốn để cho phép thiết lập các giá trị unset, hãy thử này:

func [ 
    "Create an object based on some words and values." 
    words [any-word! block!] "Word or block of words" 
    values [any-type!] "Value or block of values" 
    /any "Allows setting words to any value, including unset" 
    /local object 
][ 
    object: make object! either block? words [length? words] [1] 
    apply :set [bind/copy/new :words object :values any] 
    object 
] 

Cả hai tạo các đối tượng với self, vì vậy nếu bạn muốn tạo một đối tượng không có self, bạn phải thực hiện một số thủ thuật huyền ảo. Xem the selfless proposal để biết chi tiết.

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