2010-11-08 5 views
6

क्या किसी ऑब्जेक्ट को अनाम संदेश भेजना संभव है?स्मॉलटॉक में फ़ंक्शन ऑब्जेक्ट्स (या बिना किसी मान वाले ब्लॉक निष्पादित: `)

" find inner product " 
reduce + (applyToAll * (transpose #(1 2 3) #(4 5 6))) 

जहां reduce, applyToAll और transpose वस्तुओं रहे हैं और +, * और दो सरणियों उन वस्तुओं को अज्ञात संदेशों के लिए पारित तर्क हैं: मैं इस तरह तीन वस्तुओं (लगता है एफपी) रचना करना चाहते हैं। क्या ब्लॉक का उपयोग करके इसे हासिल करना संभव है? (लेकिन value: का कोई स्पष्ट उपयोग नहीं है)।

उत्तर

5

शायद आप वास्तव में क्या करना चाहते हैं वह स्मॉलटॉक के अंदर एक डीएसएल परिभाषित करता है?

With HELVETIA we explore a lightweight approach to embed new languages into the host language. The approach reuses the existing toolchain of editor, parser, compiler and debugger by leveraging the abstract syntax tree (AST) of the host environment. Different languages cleanly blend into each other and into existing code.

+0

लेकिन जब आप इसे करना चाहते हैं, और कर सकते हैं, शायद आपको नहीं करना चाहिए। कम से कम इस समस्या को हल करने के लिए नहीं। –

5
aRealObject reduceMethod: +; 
      applyToAll: *; 
      transpose: #(#(1 2 3) #(4 5 6)); 
      evaluate 

काम करेगा जब रीयलऑब्जेक्ट ने सही तरीकों को परिभाषित किया है। आपको ब्लॉक की आवश्यकता कहां है?

3

आप doesNotUnderstand: के लिए देख रहे हैं। यदि reduce एक ऐसी वस्तु है जो + लागू नहीं करती है लेकिन आप इसे किसी भी तरह भेजते हैं, तो इसके बजाय इसकी doesNotUnderstand: विधि लागू की जाएगी। आम तौर पर यह सिर्फ एक त्रुटि उठाता है। लेकिन आप डिफ़ॉल्ट को ओवरराइड कर सकते हैं, और चयनकर्ता + और अन्य तर्क तक पहुंच सकते हैं और जो भी आप उन्हें पसंद करते हैं।

सादगी के लिए, कक्षा Reduce बनाएं। अपने वर्ग की तरफ, विधि को परिभाषित:

doesNotUnderstand: aMessage 
    ^aMessage argument reduce: aMessage selector 

तो फिर तुम इसे इस तरह उपयोग कर सकते हैं:

Reduce + (#(1 2 3) * #(4 5 6)) 

जो एक स्क्वीक कार्यक्षेत्र में 32 उत्तर, अपेक्षा के अनुरूप।

यह काम करता है क्योंकि * पहले से ही उपयुक्त अर्थशास्त्र के साथ संग्रह के लिए लागू किया गया है।

doesNotUnderstand: aMessage 
    ^aMessage argument collect: [:e | e reduce: aMessage selector] 

और भी SequenceableCollection को यह पद्धति जोड़ें::

वैकल्पिक रूप से, इस वर्ग के साइड विधि के साथ एक वर्ग ApplyToAll जोड़ने

transposed 
    ^self first withIndexCollect: [:c :i | self collect: [:r | r at: i]] 

तो फिर तुम लिख सकते हैं

Reduce + (ApplyToAll * #((1 2 3) #(4 5 6)) transposed) 

जो आपके मूल विचार के बहुत करीब है।

संबंधित मुद्दे