مولدها
دوشنبه 29 آذر 1389 7:40 AM
عبارات در Icon اغلب فقط یک مقدار برمی گردانند، برای نمونه، x<5 با موفقیتی با مقدار 5 یا شکست ارزیابی خواهد شد. مثالهایی از every و to. every سبب میشود تا to تا زمانی که شکست بخورد به برگرداندن مقادیر ادامه دهد. مولدها یکی از مفاهیم کلیدی در Icon هستند. مولدها بسیاری از ساختارهای حلقهای را، بصورت بسیار صریح تر، در این زبان هدایت میکنند. برنامه نویس حلقهای نمینویسد و نیازی به مقایسه شرط نیست، Icon همه این کارها را برای او انجام میدهد. Icon شامل چندین مولدساز است. نحو alternator اجازه میدهد یک سری از آیتمها، تا هنگامی که یکی شکست بخورد، به ترتیب تولید شوند: 1 | "hello" | x<5، اگر x از 5 کمتر باشد، میتواند "1"، "hello" و "5" را تولید کند. متناوب سازها میتوانند در بسیاری از حالتها مانند "or" خوانده شوند، برای نمونه :
if y < (x | 5) then write(«y=», y)
اگر از x یا 5 کوچکتر باشد، این کد مقدار y را در خروجی خواهد نوشت. Icon بصورت ساختاری تمام مقادیر را از چپ به راست چک میکند تا اولین موفقیت رخ دهد یا لیست خالی شود و شکست را برگرداند. یادآوری میشود که توابع فقط تا زمانی که فراخوانیهای شامل آنها شکست نخورد، فراخوانی خواهند شد، بنابراین این مثال را میتوان بصورت کوتاه تر، به شکل زیر نوشت :
write(«y=», (x | 5) > y)
یک مولد ساده دیگر to است که میتواند اعداد صحیح تولید کند، every write(1 to 10) دقیقا همانگونه که نشان میدهد عمل خواهد کرد. نحو bang هر آیتم یک لیست را تولید میکنند. every write(!aString) هر کاراکتر aString را در یک خط جدید خواهد نوشت. اثبات قدرت این مفهوم، مقایسه عملگرهای رشتهاست. اغلب زبانها تابعی با نام find یا indexOf دارند که موقعیت یک رشته را در رشته دیگر برمی گرداند. در مقایسه با :
s = «All the world's a stage. And all the men and women merely players»;
i = indexOf("the", s)
این کد 4 را به عنوان اولین موقعیت ظاهر شدن کلمه "the" برخواهد گرداند. برای پیدا کردن نمونه بعدی "the" از تناوب استفاده میشود، , i = indexOf("the", s, 5)، 5 در انتها بیان میکند که باید از موقعیت 5 به بعد جستجو شود. برای یافتن تمام دفعات ظاهر شدن "the"، یک حلقه باید استفاده شود...
s = «All the world's a stage. And all the men and women merely players»;
i = indexOf("the", s)
while i != -1 {
write(i);
i = indexOf("the", s, i+1);
}
در Icon تابع find یک مولد است، و نمونه بعدی از رشته را تا زمانی که در انتهای رشته شکست بخورد در هر دفعه بازخواهد گرداند. همان کد در Icon میتواند اینطور نوشته شود :
s := «All the world's a stage. And all the men and women merely players»
every write(find("the",s))
Find، موقعیت نمونه بعدی "the" را هربار بازخواهد گرداند و تا زمانی که به انتهای رشته برسد ادامه مییابد. البته زمانهایی هست که شما میخواهید عمدا رشتهای را بعد از نقطهای از ورودی بیابید، برای نمونه، شما ممکن است بخواهید یک فایل متنی را که شامل دادههای یک جدول متقاطع است بررسی کنید. اجرای هدفگرا در اینجا بخوبی عمل خواهد کرد و به این صورت میتواند مورد استفاده قرار گیرد :
write(5 < find("the", s))
اگر "the" بعد از موقعیت 5 ظاهر شود، موقعیت برگردانده خواهد شد، در غیر این صورت مقایسه شکست خواهد خورد و مانند قبل، شکست را به write() منتقل خواهد کرد. در این کد یک ترفند کوچک وجود دارد که نیاز به ملاحظه دارد : مقایسه مقدار سمت راست را برمی گرداند، بنابراین لازم است که find را در سمت راست مقایسه قرار دهیم. اگر 5 در سمت راست قرار گیرد، 5 نوشته خواهد شد. Icon چند ساختار کنترلی را برای حلقه مولدها اضافه میکند. عملگر every شبیه whileاست، ایجاد حلقه میکند و با رسیدن به شکست، حلقه پایان مییابد.
every k := i to j do write(someFunction(k))
چرا every را بجای حلقه while در این حالت استفاده میکنیم؟ چون while مجددا نتیجه اولیه را مقداردهی میکند اما every همه نتایج را تولید میکند. نحو every مانند بلوکها در Smalltalk مقادیر را به تابع میفرستد. برای نمونه، حلقه بالا میتواند بصورت زیر بازنویسی شود :
every write(someFunction(i to j))
کاربران میتوانند با استفاده از کلمه کلیدی suspend به آسانی مولدهای جدید ایجاد کنند :
procedure findOnlyOdd(pattern, theString) every i := find(pattern, theString) do if i % 2 = 1 then suspend i end
این مثال روی theString که از find برای پیدا کردن الگو استفاده میکند دور میزند. وقتی نمونهای پیدا شود، و موقعیت فرد باشد، موقعیت از تابع با suspend برگردانده میشود. در غیر این صورت return suspend در جایی که در مولدهای عمومی نوشته میشود.