Theory
એની એ જ 3 લીટીઓ, 14 વાર
ShopKeeper એક લીટીનો સરવાળો (ભાવ ગુણ્યા જથ્થો, ઓછું કોઈ વળતર) 14 જુદી જુદી જગ્યાએ ગણે છે: ગલ્લા પર, દિવસના અહેવાલમાં, પાછું લેવાના પડદા પર...
આ ગંધ તમે BCA403 અને BCA104 થી ઓળખો છો: વારંવાર દોહરાતી logic એક જ નામવાળી જગ્યાએ રહેવી જોઈએ, અને જ્યાં જરૂર પડે ત્યાં બોલાવાવી જોઈએ.
VB.NET એ વિચારને procedure ના 2 પ્રકારમાં વહેંચે છે, અને એ વહેંચણી પરીક્ષામાં ગુણ અપાવે એવી છે: Sub કશુંક કરે છે; Function કશાકનો જવાબ આપે છે. ખોટી પસંદગી એટલે ગુમાવેલા ગુણ અને અણઘડ code.
Theory
Module, Sub, Function
Module એ એવું પાત્ર છે જેના procedures સહિયારા હોય છે: કોઈ object બનાવ્યા વગર જ બોલાવી શકાય (એટલે કે Java નું static, પણ VB ના પોશાકમાં). Console programs એવા કોઈ એક Module ની અંદરના Sub Main થી શરૂ થાય છે.
Sub PrintBill(...) કોઈ કામ કરે છે; એ કશું પાછું આપતું નથી. એ End Sub થી પૂરું થાય છે.
Function LineTotal(...) As Double ગણતરી કરે છે અને એક કિંમત પાછી આપે છે: પાછો આપવાનો type એ As પછી આવે છે, અને જવાબ Return વાટે બહાર નીકળે છે. એ End Function થી પૂરું થાય છે.
સાદો નિયમ: બોલાવનારને કોઈ કિંમત પાછી જોઈતી હોય તો એ Function છે; અને બોલાવનારને ફક્ત કોઈ અસર જોઈતી હોય તો એ Sub છે.
Practical
Billing ના મદદગારો, ચારેય લક્ષણો એકસાથે
Module Billing
' Optional parameter: બોલાવનાર એને છોડી દે ત્યારે મૂળભૂત કિંમત વપરાય
Function LineTotal(ByVal price As Double, ByVal qty As Integer,
Optional ByVal discount As Double = 0) As Double
Return price * qty * (1 - discount)
End Function
' ParamArray: ગમે તેટલી લીટીઓના સરવાળા સ્વીકારે છે
Function GrandTotal(ByVal ParamArray lines() As Double) As Double
Dim sum As Double = 0
For Each l As Double In lines
sum += l
Next
Return sum
End Function
Sub Main()
Dim t1 As Double = LineTotal(40, 3) ' 120 (વળતર નહીં)
Dim t2 As Double = LineTotal(100, 2, 0.1) ' 180 (10 ટકા વળતર)
MsgBox("Bill: " & GrandTotal(t1, t2)) ' Bill: 300
End Sub
End Module
Theory
ByVal અને ByRef: નકલ કે વસ્તુ પોતે
દરેક parameter બેમાંથી કોઈ એક રીતે મુસાફરી કરે છે:
- ByVal (મૂળભૂત): procedure ને એની નકલ મળે છે; એ ગમે તે કરે, બોલાવનારનું variable અડ્યા વગરનું જ રહે છે
- ByRef: procedure ને બોલાવનારનું variable પોતે મળે છે; અંદર થતી કિંમતની ફાળવણી એને બહાર પણ બદલી નાખે છે
Sub ApplyFestivalDiscount(ByRef price As Double)
price = price * 0.9
End Sub
ApplyFestivalDiscount(rate) પછી બોલાવનારનું rate ખરેખર ઘટી ગયું હોય છે. એ જ શરીર ByVal સાથે હોત તો એ ફક્ત નકલ પર વળતર લગાડત અને બહાર કશું બદલાત નહીં.
Quiz
Sub Cut(ByVal p As Double) : p = p - 10 : End Sub. બોલાવનાર: Dim price As Double = 50 : Cut(price) : MsgBox(price). શું દેખાશે?
- 40: Sub એ price માંથી 10 બાદ કરી નાખ્યા
- 50: Cut એ ફક્ત પોતાની નકલ બદલી; ByVal બોલાવનારના variable ને સાચવે છે
- Compile error: Sub પોતાના parameters બદલી શકતું નથી
- 0: Sub પૂરું થાય ત્યારે price ફરી શૂન્ય થઈ જાય છે
Show the answer
50: Cut એ ફક્ત પોતાની નકલ બદલી; ByVal બોલાવનારના variable ને સાચવે છે
ByVal Cut ના હાથમાં p નામની એક નકલ મૂકે છે; બાદબાકી એ નકલ પર થાય છે, અને Sub પૂરું થતાં જ એ નકલ ઊડી જાય છે, એટલે બોલાવનારને હજી 50 જ દેખાય છે. વિકલ્પ A એ વર્ણવે છે જે ByRef એ કર્યું હોત, અને signature માં એક જ શબ્દનો આ ફરક એ જ આખો પ્રશ્ન છે. વિકલ્પ C ખોટો છે: parameter ને બદલવું કાયદેસર છે, બસ ByVal હેઠળ એની અસર ફક્ત અંદર જ મર્યાદિત રહે છે. ByVal એ VB.NET નું મૂળભૂત વલણ હોવાથી નિષ્કર્ષ રાહત આપનારો છે: તમે જાતે સ્પષ્ટપણે ByRef લખીને ન સોંપો ત્યાં સુધી procedures તમારાં variables ને બગાડી શકતાં નથી.
Think first
બિલને હાથે ટ્રેસ કરો
ઉપરના listing પ્રમાણે: LineTotal(40, 3), પછી LineTotal(100, 2, 0.1), અને પછી બંનેનું GrandTotal. Tap કરતાં પહેલાં ત્રણેય આંકડા જાતે ગણો.
Show the answer
LineTotal(40, 3): વળતર લખ્યું જ નથી, એટલે Optional વાળી મૂળભૂત કિંમત 0 લાગુ પડે છે: 40 × 3 × 1 = 120. LineTotal(100, 2, 0.1): 100 × 2 × 0.9 = 180. GrandTotal(120, 180): ParamArray એ બે કિંમતોને array તરીકે મેળવે છે અને loop એમનો સરવાળો કરે છે: 300.
ધ્યાન આપો કે દરેક લક્ષણ પોતાની જગ્યા કમાઈ લે છે: મૂળભૂત કિંમતે સામાન્ય કિસ્સામાં લખવાનું બચાવ્યું, અને ParamArray એ બિલમાં જેટલી લીટીઓ હતી બરાબર એટલી જ લીધી: આજે 2, કાલે 9, પણ call એનો એ જ.
Watch out
ગોઠવણના એ નિયમો જે પરીક્ષકો પૂછે છે
Optional parameters એ મૂળભૂત કિંમત જાહેર કરવી જ પડે (Optional ByVal d As Double = 0) અને એ બધા ફરજિયાત parameters પછી જ આવવા જોઈએ: પહેલાં Optional અને પછી ફરજિયાત લખો તો compile થતું જ નથી.
ParamArray છેલ્લો parameter હોવો જ જોઈએ, અને એ એક જ હોઈ શકે.
Return વગરનું Function: જે રસ્તે થઈને કદી Return ન થાય એ રસ્તો પાછો એ type ની મૂળભૂત કિંમત આપી દે છે (સંખ્યાઓ માટે 0) અને સામાન્ય રીતે ખોટું બિલ પણ: એટલે દરેક રસ્તે સ્પષ્ટપણે Return કરાવો.
Theory
Java માંથી ભાષાંતર કરવું
એક વાર મેળ બેસાડી લો: Module ના procedures એટલે Java ના static methods; Sub એટલે void; અને Function એટલે type વાળો method. Java પાસે ByRef જેવું કશું નહોતું (object ના references કિંમત તરીકે મોકલાતા, જે નજીક આવે પણ સરખું નહીં), Optional વાળી મૂળભૂત કિંમતો પણ નહોતી (એને બદલે તમે overload કરતા હતા), અને ParamArray ની જગ્યાએ ત્યાં varargs (String...) હતું. એટલે અહીં VB.NET મોટે ભાગે વધુ સગવડભર્યું છે. આ મદદગારો Unit 3 માં button દબાવ્યે ચાલતો code બની જશે: ગલ્લાનું Total નું button LineTotal ને બરાબર એ જ રીતે બોલાવશે જે રીતે આજે Main બોલાવે છે.
Summary
Key takeaways
- Module એટલે સહિયારા procedures નું પાત્ર; Sub Main એ console નું પ્રવેશદ્વાર છે.
- Sub કોઈ કામ કરે છે (કશું પાછું આપતું નથી); Function ... As Type એક કિંમત Return વાટે પાછી આપે છે.
- ByVal (મૂળભૂત) નકલ મોકલે છે: બોલાવનારનું variable સલામત રહે છે; ByRef variable પોતે મોકલે છે: ફેરફાર ટકી જાય છે.
- Optional parameters ને મૂળભૂત કિંમત જોઈએ અને એ ફરજિયાત parameters પછી બેસે છે.
- ParamArray ગમે તેટલા arguments ને એક array માં ભેગા કરી લે છે; અને એ ફક્ત છેલ્લો parameter જ હોઈ શકે.
- ગણેલું બિલ: 40 ગુણ્યા 3 બરાબર 120, 100 ગુણ્યા 2 ગુણ્યા 0.9 બરાબર 180, અને કુલ સરવાળો 300.
- યાદ રાખવાની કડી: Sub કરે છે, Function જવાબ આપે છે, અને ByRef મૂળ વસ્તુ જ સોંપી દે છે.