سؤال

العمل مع TCL و أود أن تنفيذ شيء من هذا القبيل نمط استراتيجية.أريد أن تمر في "استراتيجية" من أجل إخراج الطباعة في TCL وظيفة لذا يمكن التبديل بسهولة بين الطباعة على الشاشة الطباعة إلى ملف سجل.ما هي أفضل طريقة للقيام بذلك في TCL ؟

هل كانت مفيدة؟

المحلول

وTCL يسمح لك لتخزين اسم الإجراء في متغير ثم استدعاء الإجراء باستخدام هذا المتغير. لذلك

proc A { x } {
   puts $x
}

set strat A
$strat Hello

وسيتم استدعاء بروك ألف وطباعة مرحبا

نصائح أخرى

وبالإضافة إلى الإجابة التي تبين كيفية تعيين إجراء متغير، يمكنك أيضا تمرير اسم إجراء كحجة لإجراء آخر. وهنا مثال بسيط:


proc foo { a } {
   puts "a = $a"
}

proc bar { b } {
   puts "b = $b"
}

proc foobar { c } {
   $c 1
}

foobar foo
foobar bar

وهذا سوف طباعة = 1 و ب = 1

وهناك مثال توسعت قليلا ما كان المذكورة أعلاه التي قد توضح خطة استراتيجية أكثر وضوحا:

proc PrintToPDF {document} {
<snip logic>
}

proc PrintToScreen {document} {
<snip logic>
}

proc PrintToPrinter {document} {
<snip logic>
}


set document "my cool formatted document here"

set printMethod "printer"


switch -- $printMethod {
    "printer" {
        set pMethodName "PrintToPrinter"
    }
    "pdf" {
        set pMethodName "PrintToScreen"
    }
    "screen" {
        set pMethodName "PrintToPDF"
    }
}

$pMethodName $document

وبصرف النظر عن استخدام proc, هل يمكن فعلا استخدام كتلة التعليمات البرمجية بدلا من ذلك.هناك عدد قليل من الاختلافات حول هذا.الأول هو الأكثر وضوحا فقط evaling ذلك.

set strategy {
    puts $x
}

set x "Hello"
eval $strategy
unset x

يعمل هذا, ولكن هناك بعض الجوانب السلبية.الأولى واضحة ، كل قطعة من التعليمات البرمجية يجب أن تتواطأ على استخدام تسمية شائعة عن الحجج.هذا محل مساحة واحدة الصداع (procs) مع آخر (المحليين) ، وهذا القول في الواقع أسوأ.

أقل وضوحا هو أن eval عمدا يفسر حجتها دون تجميع بايت كود.هذا هو لأنه يفترض أن التقييم سوف يطلق مع ديناميكيا ، عادة ما تكون فريدة من نوعها الحجج ، وتجميع إلى بايت كود لن يكون مجديا إذا كان بايت كود لن تستخدم إلا مرة واحدة ، نسبة إلى مجرد تفسير كتلة فورا.هذا هو أسهل لإصلاح ذلك المصطلح:

set x "Hello"
if 1 $strategy
unset x

if, على عكس eval, هل ترجمة و ذاكرة التخزين المؤقت لها كتلة التعليمات البرمجية.إذا كان $strategy كتلة أي وقت مضى واحد فقط أو عدد قليل من مختلف القيم الممكنة ، ثم هذا يعمل بشكل جيد جدا.

هذا لا يساعد على الإطلاق مع yuckiness من تمرير الوسائط إلى كتلة مع المتغيرات المحلية.هناك الكثير من الطرق حول ذلك ، مثل القيام التبديلات في نفس الطريق المعارف التقليدية لا التبديلات على قيادة الحجج مع %'s.يمكنك محاولة القيام ببعض hackish الأشياء باستخدام uplevel أو upvar.على سبيل المثال هل يمكن أن تفعل هذا:

set strategy {
    puts %x
}

if 1 [string map [list %% % %x Hello] $strategy]

على فرصة قبالة أن الحجج التي يتم تمريرها لا تتغير كثيرا, هذا يعمل بشكل جيد من حيث بايت كود التجميع.إذا من ناحية أخرى ، فإن الحجة تغييرات في كثير من الأحيان ، يجب عليك استخدام eval بدلا من if 1.هذا ليس أفضل بكثير على أية حال ، من حيث الحجج.هناك أقل من احتمالات الارتباك حول ما مرت و ما ليس لأنك باستخدام بناء جملة خاص.أيضا هذا مفيد في حال كنت تريد استخدام متغير الاستبدال قبل العودة كتلة رمز:كما في set strategy "$localvar %x".

لحسن الحظ, tcl 8.5 له صحيح مجهول وظائف, باستخدام apply الأوامر.الكلمة الأولى إلى تطبيق الأوامر ستكون قائمة من الحجج الجسم ، كما لو كانت تلك الحجج proc خرجن.الحجج المتبقية التي تم تمريرها إلى المجهول الأمر كما الحجج على الفور.

set strategy [list {x} {
    puts $x
}]

apply $strategy "Hello"

كيف حول استخدام متغير الوظائف ؟ لا أتذكر الكثير TCL (انها كانت فترة من الوقت...) ولكن ربما واحدة من هذه سوف تفعل ما عليك:

  • [$var param1 param2]
  • [$var] param1 param2
  • $var param1 param2

إذا كنت مخطئا, أي شخص حر في أن تصحح لي.

% set val 4444
4444

% set pointer val
val

% eval puts $$pointer
4444

% puts [ set $pointer ]
4444

% set tmp [ set $pointer ]
4444

لتوضيح لماذا يعمل أسلوب جاكسون، أن نتذكر أن في TCL، <م> كل شيء هو سلسلة. ما إذا كنت تعمل مع سلسلة حرفية، وهي وظيفة، متغير، أو أيا ما كان، <م> كل شيء هو سلسلة. يمكنك تمرير "مؤشر الدالة" مثلك يمكن أن "مؤشر البيانات": ببساطة استخدام اسم الكائن مع عدم وجود الرائدة "$"

وجميع ما ذكر أعلاه، على الرغم من عند الانتقال من مساحة الاسم إلى مساحة الاسم، قد ترغب في استخدامه كقاعدة [namespace current ]::proc_name عابرة، لضمان أن لا تحصل على أي فواصل.
للحصول على طرق OO، فسوف تحتاج إلى متابعة ما هو موجود في هذا الموضوع: تمرير طريقة لكائن معين كحجة مساهمة في تى سى ال
التوفيق.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top