द्वारा पैरामीटर प्रदान करने के इस सवाल एम में संदर्भ द्वारा पारित करने के विषय पर है (मेरा एक संबंधित सवाल यहाँ है simple question on passing data between functions)एक struct का उपयोग संदर्भ
जब मैं संदर्भ द्वारा चीजों को पारित करने के लिए एक रास्ता खोजने के लिए कोशिश कर रहा था Unevaluted[]
या HoldFirst[]
का उपयोग किए बिना, मैंने गलती से इस विधि को मारा और यह वास्तव में मेरे लिए अच्छा काम कर रहा है, भले ही मुझे यह समझ में नहीं आता कि यह कैसे काम करता है और इसका उपयोग करने के किसी भी छिपे जोखिम। इसलिए मैं इसे विशेषज्ञों को यहां दिखाना चाहता हूं और पूछता हूं कि क्या उन्हें लगता है कि यह उपयोग करना सुरक्षित है (मेरे पास बहुत बड़ा डेमो है और उन्हें प्रबंधित करने में सहायता के लिए विभिन्न structs की संख्या में पैरामीटर पैकेज करने की आवश्यकता है, और इस तरह मैंने इसे पाया विधि जब मैं चीजों की कोशिश कर रहा था)।
यहाँ विधि है: सबसे पहले हम जानते हैं कि एक का पालन नहीं कर लिख सकते हैं:
Remove[p]
foo[p_] := Module[{u},
u = Table[99, {10}];
p = u
];
p = 0;
foo[p];
एक 'पी' को अद्यतन करने के लिए ऊपर दिए गए बनने के लिए कॉल करने के लिए बदलने के लिए है जिस तरह से
foo[[email protected]];
या foo[]
को HoldFirst
के साथ परिभाषित करके।
लेकिन यहाँ, जिस तरह से मैंने पाया है, जो संदर्भ द्वारा पारित करता है इनमें से किसी के बिना:
मैं एक struct (मैं अब इस वैसे भी करते हैं) में सभी मापदंडों रखा, और struct गुजरती हैं, और फिर एक foo[]
अंदर struct के क्षेत्र अद्यतन कर सकते हैं और अद्यतन रास्ता समारोह कॉल से वापस में परिलक्षित होगा:
Remove[parms]
foo[parms_] := Module[{u},
u = Table[99, {10}];
parms["p"] = u
];
parms["p"] = 0;
foo[parms];
अब, parms["p"]
नई सूची {99, 99, 99, 99, 99, 99, 99, 99, 99, 99}
एस निहित ओ, parms
foo[]
के अंदर 0wrपास करने के लिए एम को बताने के बिना foo[]
के अंदर ओवरराइट/अपडेट किया गया था!
मैंने अपने कार्यक्रम में यह कोशिश की, और मुझे कोई अजीब दुष्प्रभाव नहीं दिख रहा है। सीडीएफ को कोई त्रुटि के साथ ठीक से अद्यतन किया गया था। मुझे नहीं पता कि यह कैसे काम करता है, क्या एम parms
के अंदर सभी क्षेत्रों को ग्लोबल के रूप में मान सकता है?
लेकिन किसी भी मामले में, मैं इस से खुश हूं क्योंकि यह मुझे अपने कई पैरामीटर को structs में पैकेज करने का एक तरीका प्रदान करता है, और साथ ही मैं संरचना के कार्यों के अंदर अद्यतन करने में सक्षम हूं।
लेकिन मेरा सवाल है: क्या आप इस विधि के साथ एक बड़ी समस्याएं देखते हैं? यह आंतरिक रूप से कैसे काम करता है? मेरा मतलब है कि एम HoldFirst
या Unevaluated
करने के बिना एम को इस गुजरने को कैसे संभालता है? मुझे पता है कि अब पैरामीटर को पहले की तरह जांचने की क्षमता खो गई है, लेकिन मेरे पास जो कुछ भी मैं चाहता हूं उसे प्राप्त नहीं कर सकता। जैसा कि मैंने पहले कहा था, एम को भाषा के हिस्से के रूप में वास्तविक निर्माण-संरचना की आवश्यकता है और इसमें एकीकृत किया गया है। लेकिन यह एक और समय के बारे में बात करने के लिए है।
बीटीडब्ल्यू, मैंने अब तक देखा है सबसे अच्छा स्ट्रक्चर इम्यूलेशन इस धागे here के अंत में लियोनीड शिफ्रिन द्वारा पोस्ट किया गया था लेकिन दुर्भाग्य से मैं इसे अपने डेमो में उपयोग नहीं कर सका क्योंकि यह डेमो में अनुमति नहीं है CDF।
धन्यवाद
अद्यतन: Btw, इस नीचे मैं क्या सोचता कैसे एम इस संभालती है।यह मेरा अनुमान है: मुझे लगता है कि param
किसी प्रकार की लुकअप टेबल है, और इसके फ़ील्ड्स का उपयोग सिर्फ एक इंडेक्स के रूप में किया जाता है (हैश टेबल हो सकता है?) फिर param["p1"]
इसमें पता होगा (मूल्य नहीं) के ढेर में एक स्थान का जहां param["p1"]
का वास्तविक मूल्य रहता है।
कुछ इस तरह:
तो, जब param
गुजर, तो समारोह foo[]
, जब param["p1"]=u
टाइपिंग के अंदर यह वर्तमान स्मृति बताया "p1"
द्वारा अप करने के लिए मुक्त किया जा करने के लिए कारण होगा, और फिर एक ढेर से आवंटित नई मेमोरी, और इसमें u
का मान कॉपी किया गया है।
और इसलिए, वापस लौटने पर, यही कारण है कि हम param["p1"]
की सामग्री को बदल चुके हैं। लेकिन वास्तव में क्या बदल गया, स्मृति की सामग्री उस पते से इंगित की जा रही है जो param["p1"]
दर्शाती है।
(वहाँ एक नाम है, जो "p1"
है, और एक पते क्षेत्र है, जो सामग्री है कि नाम "p1"
का प्रतिनिधित्व करता है ओर इशारा करता है) लेकिन तब इसका मतलब है, कि पता ही है, जो "p1"
का प्रतिनिधित्व करता है बदला है, लेकिन देखने नाम स्वयं (जो "पी 1" है) नहीं बदला।
इसलिए, जैसा कि नाम स्वयं नहीं बदला गया था, होल्डफर्स्ट का उपयोग करने की कोई आवश्यकता नहीं थी, भले ही इस नाम का प्रतिनिधित्व करने वाले डेटा के आधार पर डेटा को संशोधित किया गया हो?
अद्यतन:
इस विधि में एक छोटी सी गड़बड़ है, लेकिन यह एक बड़ी बात यह आस-पास काम करने के लिए नहीं है: जब इस अनुक्रमित वस्तु विधि का उपयोग कर बातें गुजर, यह पता चला है कि एक नहीं कर सकते वस्तु का हिस्सा संशोधित करें। उदाहरण के लिए, इस नीचे काम नहीं करता:
foo[param_] := Module[{},
param["u"][[3]] = 99 (*trying to update PART of u *)
];
param["u"] = Table[0, {5}];
foo[param];
उपरोक्त त्रुटि
Set::setps: "param[u] in the part assignment is not a symbol"
देता है लेकिन वैकल्पिक हल आसान है। तब स्थानीय प्रतिलिपि का (भाग) को अद्यतन पूरे क्षेत्र है कि एक इसका हिस्सा अद्यतन करने के लिए चाहता है की स्थानीय प्रतिलिपि बनाने के लिए,, फिर वापस क्षेत्र के लिए प्रति लिखते हैं, इस
foo[param_] := Module[{u = param["u"]}, (* copy the whole field *)
u[[3]] = 99; (*update local copy *)
param["u"] = u (*now update the field, ok *)
];
param["u"] = Table[0, {5}];
foo[param];
खैर की तरह। यदि कोई क्षेत्र के हिस्से को अपडेट कर सकता है तो बेहतर होगा, इसलिए 'विशेष' हैंडलिंग की आवश्यकता नहीं होगी। लेकिन कम से कम काम इतना बुरा नहीं है।
अद्यतन पूर्णता के लिए, मैंने सोचा कि मैं अनुक्रमित वस्तुओं और आसपास के काम का उपयोग करने के बारे में एक और छोटी बात का उल्लेख करता हूं।
मैं
param[u] = {1, 2, 3}
param[u][[1 ;; -1]]
कौन सा {1,2,3}
रिटर्न की उम्मीद के रूप में लिखा था।
तब मैंने पाया कि param[u]
के बजाय मैं [email protected]
का उपयोग कर सकता हूं, जिसने वास्तव में बहुत से ठोस ब्रैकेट्स को सिरदर्द देने के लिए शुरू कर दिया है।
लेकिन तब
जब मैं टाइप किया[email protected][[1 ;; -1]]
पहले की तरह ही जवाब वापस पाने के लिए उम्मीद कर रहा, ऐसा नहीं किया। एक एक त्रुटि हो जाता है, (मुझे लगता है कि मैं जानता हूँ कि क्यों, ऑपरेटर पूर्वता मुद्दा, लेकिन उस समय अब नहीं है), सिर्फ इतना कहना है कि वैकल्पिक हल के लिए आसान है चाहता था, या तो एक param[u][[1 ;; -1]]
का उपयोग करें या ([email protected])[[1 ;; -1]]
उपयोग कर सकते हैं मुझे पसंद है ([email protected])[[1 ;; -1]]
और, इसलिए मैं अब अनुक्रमित वस्तुओं के अंदर सूचियों तक पहुंचने के लिए उपयोग कर रहा हूं।
नोटेशन [email protected]
उतना करीब है जितना मैं मानक रिकॉर्ड नोटेशन प्राप्त कर सकता हूं जो param.u
है इसलिए अब मैं अनुक्रमित वस्तुओं के साथ खुश हूं, और ऐसा लगता है कि यह वास्तव में अच्छी तरह से काम कर रहा है। देखने के लिए कुछ मामूली चीज़ों को देखने के लिए।
इस प्रश्न में बहुत कुछ चल रहा है। क्या आपके पास एक विशिष्ट चीज है जिसे आप प्राप्त करने का प्रयास कर रहे हैं? –
@ माइकबेंटगेई, मैं मूल रूप से यह पूछ रहा हूं कि इसे कैसे कार्यान्वित किया जाता है, और यह क्यों काम करता है क्योंकि एक कार्य के अंदर पैरामीटर को संशोधित करने में सक्षम है, जिसे एम में अनुमति नहीं है, क्योंकि एम में सामान्य पासिंग मूल्य से है। लेकिन यहां यह हो रहा है और होल्डफर्स्ट का उपयोग किए बिना और अनियंत्रित उपयोग किए बिना। इसे कैसे समझाओ? – Nasser
नासर, कृपया मेरा जवाब पढ़ें और मुझे बताएं कि अस्पष्ट क्या है। –