ഷെൽ സ്ക്രിപ്റ്റിംഗിനൊപ്പം പ്രവർത്തന സങ്കീർണ്ണതകളിലേക്ക് ആഴത്തിൽ - ഭാഗം VII


\ഷെൽ സ്ക്രിപ്റ്റുകളിൽ ഫംഗ്ഷനുകൾ മനസ്സിലാക്കുകയും എഴുതുകയും ചെയ്യുക എന്നതിനെക്കുറിച്ചുള്ള എന്റെ മുൻ ലേഖനം, ഷെൽ സ്ക്രിപ്റ്റുകൾക്ക് കീഴിൽ ഫംഗ്ഷനുകൾ എങ്ങനെ എഴുതാം എന്നതിനെക്കുറിച്ചുള്ള ഒരു അടിസ്ഥാന ആശയം നിങ്ങൾക്ക് നൽകിയിട്ടുണ്ടാകാം. ഇപ്പോൾ ലോക്കൽ വേരിയബിളുകളുടെ ഉപയോഗം, ആവർത്തനം തുടങ്ങിയ പ്രവർത്തന സവിശേഷതകളിലേക്ക് കൂടുതൽ ആഴത്തിൽ എത്തേണ്ട സമയമാണിത്.

എന്താണ് ഒരു വേരിയബിളിനെ ലോക്കൽ ആക്കുന്നത്? ഇത് വേരിയബിൾ പ്രഖ്യാപിച്ചിരിക്കുന്ന പ്രത്യേക ബ്ലോക്കിനെ ആശ്രയിച്ചിരിക്കുന്നു. ലോക്കൽ ആയി പ്രഖ്യാപിച്ച ഒരു വേരിയബിൾ, അത് ദൃശ്യമാകുന്ന കോഡിന്റെ ബ്ലോക്കിൽ നിന്ന് ആക്uസസ് ചെയ്യാൻ കഴിയും, അതായത് അതിന്റെ വ്യാപ്തി പ്രാദേശികമാണ്. ഈ കാര്യം വിശദീകരിക്കുന്നതിന് താഴെയുള്ള ഒരു ഉദാഹരണം നോക്കാം.

#!/bin/bash 

func( ) { 
	local i=10 
	j=20 
	echo "i from func = $i" 
	echo "j from func = $j" 
} 

echo "i outside func = $i" 
echo "j outside func = $j" 

func 

echo "i outside func = $i" 
echo "j outside func = $j" 

exit 0

മുകളിലെ സ്ക്രിപ്റ്റ് എക്സിക്യൂട്ട് ചെയ്യുമ്പോൾ ഔട്ട്പുട്ട് ആയിരിക്കും.

i outside func = 
j outside func = 
i from func = 10 
j from func = 20 
i outside func = 
j outside func = 20

ആദ്യത്തെ 2 എക്കോ സ്റ്റേറ്റ്uമെന്റുകൾ എക്uസിക്യൂട്ട് ചെയ്യുമ്പോൾ ഫംഗ്uഷൻ func ഇതുവരെ വിളിച്ചിട്ടില്ല എന്നതിനാലാണിത്. ഫംഗ്uഷൻ func എന്ന് വിളിച്ചതിന് ശേഷം അതേ 2 എക്കോ സ്റ്റേറ്റ്uമെന്റുകൾ മറ്റൊരു ഫലം നൽകുന്നു. ഇപ്പോൾ func-നുള്ളിൽ പ്രഖ്യാപിച്ച വേരിയബിൾ j, ലോക്കൽ അല്ല, പിന്നീട് ആക്സസ് ചെയ്യാൻ കഴിയും.

അങ്ങനെ j എന്നതിനുള്ള മൂല്യം 20 ആയി മാറുന്നു. പ്രാദേശിക വേരിയബിളായ i സംബന്ധിച്ചെന്ത്? അതിന്റെ വ്യാപ്തി ഫംഗ്uഷൻ func ഉള്ളതിനാൽ, മൂല്യം 10 പുറത്ത് നിന്ന് ആക്uസസ് ചെയ്യാൻ കഴിഞ്ഞില്ല. func-നുള്ളിൽ സാധാരണയായി പ്രഖ്യാപിച്ചിരിക്കുന്ന വേരിയബിൾ j സ്ഥിരസ്ഥിതിയായി ആഗോളമാണെന്ന് ശ്രദ്ധിക്കുക.

ഇപ്പോൾ നിങ്ങൾക്ക് പ്രാദേശിക വേരിയബിളുകളും ഫംഗ്uഷൻ ബ്ലോക്കുകൾക്കുള്ളിൽ അവ എങ്ങനെ ഉപയോഗിക്കാമെന്നും പരിചിതമാണ്. ഫംഗ്uഷനുകൾക്ക് കീഴിലുള്ള ഏറ്റവും രസകരമായ വിഭാഗമായ ആവർത്തനത്തിലേക്ക് നമുക്ക് പോകാം.

ഒരു ഫംഗ്uഷൻ വിളിക്കുന്നതിനെ പൊതുവെ ആവർത്തന നടപടിക്രമം എന്ന് വിളിക്കുന്നു. അല്ലെങ്കിൽ അതേ അൽഗോരിതത്തിന്റെ ലളിതമായ പതിപ്പ് ഉപയോഗിച്ച് ഒരു അൽഗോരിതം പ്രകടിപ്പിക്കുന്നതായി ഇതിനെ നിർവചിക്കാം. ഒരു സംഖ്യയുടെ ഫാക്uടോറിയൽ കണ്ടെത്തുന്നതിനുള്ള ഉദാഹരണം പരിഗണിക്കുക. n എന്ന് ഞങ്ങൾക്കറിയാം! = 1 x 2 x 3 x … x (n-1) x n. അങ്ങനെ നമുക്ക് ഒരു ആവർത്തന ബന്ധം ഇങ്ങനെ എഴുതാം:

n! = (n-1)! x n

അതിനാൽ ഒരേ ഫംഗ്uഷനെ ആവർത്തിച്ച് വിളിക്കാനും ഓരോ കോളിൽ നിന്നുമുള്ള റിട്ടേൺ മൂല്യം മുമ്പത്തെ ഫലത്തിനൊപ്പം ഗുണിക്കാനും ഞങ്ങൾക്ക് എളുപ്പമാണ്, അതായത്.

5! = 4! x 5
4! = 3! x 4
3! = 2! x 3
2! = 1! x 2
1! = 0! x 1

ലോക്കൽ വേരിയബിളുകളും ആവർത്തനവും ഉപയോഗിച്ച് ഒരു സംഖ്യയുടെ ഫാക്uടോറിയൽ കണ്ടെത്തുന്നതിന് ഒരു സ്uക്രിപ്റ്റ് എഴുതാൻ ഞങ്ങൾ ഇവിടെ ശ്രമിക്കുന്നു.

#!/bin/bash 

fact( ) { 
	local num=$1 
	if [ $num -eq 0 ]; then 
		ret=1 
	else 
		temp=$((num-1)) 
		fact $temp 
		ret=$((num*$?)) 
	fi 
	return $ret 
} 

fact 5 

echo "Factorial of 5 = $?" 

exit 0

ഓരോ കോളിലും ഓരോ n-1 മൂല്യവും സംഭരിക്കാൻ ഉപയോഗിക്കുന്ന ഒരു ലോക്കൽ വേരിയബിളാണ് num. ഇവിടെ അടിസ്ഥാന വ്യവസ്ഥ സംഖ്യ പൂജ്യത്തിന് തുല്യമാണോ അല്ലയോ എന്ന് പരിശോധിക്കുന്നു (0! = 1 എന്നതിനാൽ, നെഗറ്റീവ് സംഖ്യകൾക്ക് ഫാക്uടോറിയൽ നിർവചിച്ചിട്ടില്ല). ഈ അടിസ്ഥാന അവസ്ഥയിൽ എത്തുമ്പോൾ അത് അതിന്റെ കോളർക്ക് മൂല്യം 1 തിരികെ നൽകുന്നു. ഇപ്പോൾ num = 1 ഒപ്പം ret = 1 x 1.

ഈ തൽക്ഷണം അത് വിളിക്കുന്നയാൾക്ക് 1 തിരികെ നൽകുന്നു. ഇപ്പോൾ num = 2, ret = 2 x 1 എന്നിങ്ങനെ. ഒടുവിൽ num = 5 റിട്ടേൺ മൂല്യം 24 ആകുകയും അവസാന ഫലം ret = 5 x 24 ആകുകയും ചെയ്യുമ്പോൾ. അവസാന ഫലം 120 പ്രാരംഭ കോളർ പ്രസ്താവനയിലേക്ക് കൈമാറുകയും പ്രദർശിപ്പിക്കുകയും ചെയ്യുന്നു.

മുകളിലെ സ്ക്രിപ്റ്റിൽ ഒരു പ്രശ്നമുണ്ട്. മുൻ ലേഖനത്തിൽ ഞാൻ വിശദീകരിച്ചതുപോലെ, ഫംഗ്ഷനുകൾക്ക് വലിയ പൂർണ്ണസംഖ്യകൾ നൽകാനാവില്ല. അതിനാൽ മേൽപ്പറഞ്ഞ പ്രശ്uനത്തിന് പരിഹാരം കണ്ടെത്തുന്നത് ഉപയോക്താക്കൾക്ക് അവശേഷിക്കുന്നു.

Q. ലോക്കൽ വേരിയബിളുകൾ ഉപയോഗിക്കാതെ നമുക്ക് ആവർത്തനം നടത്താൻ കഴിയുമോ? അതെ എന്നാണ് ഉത്തരം.

റികർഷൻ ഉപയോഗിച്ച് ഫിബൊനാച്ചി സീരീസ് പ്രദർശിപ്പിക്കുന്നതിന് ഇനിപ്പറയുന്ന ഉദാഹരണം നോക്കുക. അടിസ്ഥാന ആവർത്തന ബന്ധം ഇതാണ്:

fib(0) = 0 
fib(1) = 1 
else 
	fib(n) = fib(n-1) + fib(n-2)

Fibonacci series using recursion

#!/bin/bash 

fib( ) { 
	a=$1 
	if [ $a -lt 2 ]; then 
		echo $a 
	else 
		((--a)) 
		b=$(fib $a) 

		((--a)) 
		c=$(fib $a) 

		echo $((b+c)) 
	fi 
} 

for i in $(seq 0 15) 
do 
	out=$(fib $i) 
	echo $out 
done 

exit 0

മുകളിലെ സ്ക്രിപ്റ്റിൽ ലോക്കൽ വേരിയബിളുകളൊന്നും ഉപയോഗിച്ചിട്ടില്ല. നിർവ്വഹണ വേളയിൽ നിങ്ങൾക്ക് തിരക്കഥയുടെ ഒഴുക്ക് മനസ്സിലാക്കാൻ കഴിയുമെന്ന് ഞാൻ പ്രതീക്ഷിക്കുന്നു.

ഇവിടെ 15 എന്ന മൂല്യം ഫിബൊനാച്ചി ശ്രേണിയിൽ പ്രദർശിപ്പിക്കേണ്ട പദങ്ങളുടെ എണ്ണത്തെ പ്രതിനിധീകരിക്കുന്നു. മുകളിലെ സ്ക്രിപ്റ്റിന്റെ നിർവ്വഹണവുമായി ബന്ധപ്പെട്ട് എന്തെങ്കിലും പ്രത്യേകത നിങ്ങൾ ശ്രദ്ധിച്ചിട്ടുണ്ടോ. കുറച്ച് സമയമെടുക്കും, അല്ലേ? സി പോലുള്ള പ്രോഗ്രാമിംഗ് ഭാഷകളിലെ ആവർത്തനത്തേക്കാൾ സ്ക്രിപ്റ്റിലെ ആവർത്തനം മന്ദഗതിയിലാണ്.

ഈ ലേഖനത്തിലൂടെ, ഷെൽ സ്ക്രിപ്റ്റിംഗിലെ ഫംഗ്ഷനുകളുടെ ഭാഗം അവസാനിപ്പിക്കാൻ ഞാൻ പദ്ധതിയിടുന്നു. അറേകളിൽ വരാനിരിക്കുന്ന ലേഖനങ്ങളും അതിലേറെയും ലഭിക്കാൻ Tecmint-ൽ അപ്ഡേറ്റ് ആയി തുടരുക...