Theory
वही 3 Lines, 14 बार
ShopKeeper एक line total (price गुणा quantity, minus कोई discount) 14 अलग जगहों पर compute करता है: till पर, day report में, return screen में...
यह smell आप BCA403 और BCA104 से पहले ही जानते हैं: repeated logic एक ही NAMED जगह पर होनी चाहिए, जहाँ भी ज़रूरत हो वहाँ से call की जाए।
VB.NET इस idea को 2 तरह के procedure में बाँटता है, और यह split graded है: एक Sub कुछ DOES करता है; एक Function कुछ ANSWERS करता है। ग़लत choose करना lost marks और awkward code है।
Theory
Module, Sub, Function
एक Module एक container है जिसके procedures shared हैं: बिना कोई object बनाए callable (Java का static, VB के कपड़ों में)। Console programs एक के अंदर Sub Main पर शुरू होते हैं।
Sub PrintBill(...) एक action perform करता है; यह कुछ return नहीं करता। End Sub से खत्म होता है।
Function LineTotal(...) As Double compute करता है और एक value return करता है: return type As के बाद आता है, answer Return से बाहर जाता है। End Function से खत्म होता है।
Thumb का rule: अगर caller को एक value वापस चाहिए, यह Function है; अगर caller को एक effect चाहिए, एक Sub है।
Practical
Billing Helpers, चारों Features एक साथ
Module Billing
' Optional parameter: default used when caller omits it
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: accepts ANY number of line totals
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 (no discount)
Dim t2 As Double = LineTotal(100, 2, 0.1) ' 180 (10% off)
MsgBox("Bill: " & GrandTotal(t1, t2)) ' Bill: 300
End Sub
End Module
Theory
ByVal और ByRef: Copy या Cheez खुद
हर parameter 2 तरीकों में से एक से travel करता है:
- ByVal (default): procedure को एक copy मिलती है; यह जो भी करे, caller का variable untouched रहता है
- ByRef: procedure को caller का variable खुद मिलता है; अंदर के assignments इसे बाहर CHANGE कर देते हैं
Sub ApplyFestivalDiscount(ByRef price As Double)
price = price * 0.9
End Sub
ApplyFestivalDiscount(rate) के बाद, caller का rate genuinely घट चुका होता है। ByVal के साथ same body copy को discount करता और बाहर कुछ नहीं बदलता।
Quiz
Sub Cut(ByVal p As Double) : p = p - 10 : End Sub. Caller: Dim price As Double = 50 : Cut(price) : MsgBox(price). क्या दिखता है?
- 40: Sub ने price में से 10 subtract कर दिया
- 50: Cut ने सिर्फ़ अपनी खुद की copy बदली; ByVal caller के variable को protect करता है
- Compile error: एक Sub अपने parameters modify नहीं कर सकता
- 0: Sub खत्म होने पर price reset हो जाता है
Show the answer
50: Cut ने सिर्फ़ अपनी खुद की copy बदली; ByVal caller के variable को protect करता है
ByVal, Cut को p नाम की एक copy देता है; subtraction उस copy के साथ होता है, जो Sub खत्म होते ही evaporate हो जाती है, तो caller अब भी 50 देखता है। Option A describe करता है कि ByRef क्या करता, और signature में एक-word का फ़र्क पूरा question है। Option C false है: एक parameter modify करना legal है, बस ByVal के तहत locally scoped। चूँकि ByVal VB.NET का DEFAULT है, takeaway comforting है: procedures आपके variables को तब तक damage नहीं कर सकते जब तक आप explicitly उन्हें ByRef से hand over न करें।
Think first
Bill को Trace कीजिए
Listing इस्तेमाल करते हुए: LineTotal(40, 3), फिर LineTotal(100, 2, 0.1), फिर दोनों का GrandTotal। Tap करने से पहले तीनों numbers compute कीजिए।
Show the answer
LineTotal(40, 3): discount omit किया गया, तो Optional default 0 apply होता है: 40 × 3 × 1 = 120। LineTotal(100, 2, 0.1): 100 × 2 × 0.9 = 180। GrandTotal(120, 180): ParamArray दोनों values को एक array की तरह receive करता है और loop इन्हें sum करता है: 300। नोटिस कीजिए हर feature अपना काम कमा रहा है: default ने common case बचाया, ParamArray ने ठीक उतनी ही lines लीं जितनी bill में थीं: आज 2, कल 9, same call।
Watch out
Placement Rules जो Examiners Test करते हैं
Optional parameters को एक default declare करना ज़रूरी है (Optional ByVal d As Double = 0) और सारे required parameters के बाद आना ज़रूरी है: Optional-फिर-required compile नहीं होता।
ParamArray हमेशा आख़िरी parameter होना चाहिए, और सिर्फ़ एक ही हो सकता है।
Return के बिना Function: जो path कभी return नहीं करता वह type का default वापस देता है (numbers के लिए 0) और usually एक ग़लत bill: हर path को explicitly Return कीजिए।
Theory
Java से Translate करना
एक बार map कीजिए: Module procedures Java के static methods हैं; Sub void है; Function एक typed method है। Java के पास कोई ByRef नहीं था (object references का by value pass होना करीब आता था पर equal नहीं), कोई Optional defaults नहीं (आप इसके बजाय overload करते थे) और varargs (String...) इसका ParamArray था। तो VB.NET यहाँ ज़्यादातर MORE convenient है। ये helpers Unit 3 में button-click code बन जाते हैं: till का Total button LineTotal को exactly वैसे ही call करेगा जैसे आज Main करता है।
Summary
Key takeaways
- Module = shared procedures का container; Sub Main console entry point है।
- Sub एक action perform करता है (कोई return value नहीं); Function ... As Type Return से एक value return करता है।
- ByVal (default) एक copy pass करता है: caller का variable safe रहता है; ByRef variable खुद pass करता है: changes stick होते हैं।
- Optional parameters को एक default value चाहिए और यह required वालों के बाद बैठते हैं।
- ParamArray किसी भी संख्या के arguments को एक array में इकट्ठा करता है; सिर्फ़ आख़िरी parameter।
- Worked bill: 40×3 = 120, 100×2×0.9 = 180, grand total 300।
- Memory hook: Sub करता है, Function answer देता है, ByRef original hand over करता है।