Afaik, OOP (for example in Java) still need which method can be override, which 
final, which abstract method(/class).

If the author didn't set those info, nothing for lib's users able to override 
or do anything the original lib.

Actually you're incorrect that a proc can be redefined across module because 
each proc defined with different module has symbol name as 
module_name.proc_name, so if there's two procs that has same arity and 
parameters types, compiler will report the error unless you call it full the 
proc symbol.

This is how you do it with closure
    
    
    #heroes.nim
    
    type
      Hero* = ref object of RootObj
      ImplementationError* = object of Exception
    
    method kill*(self, victim: Hero, howItKilled: proc(casualty: Hero) = nil) =
      if howItKilled.isNil:
        raise newException(ImplementationError,
          "Hero descendants should describe how they're killed")
      else:
        howItKilled victim
    
    
    
    #jedi.nim
    
    import heroes
    
    type
      OB1* = ref object of Hero
      Yoda* = ref object of Hero
    
    method kill*(self: Hero, ob1: OB1,
                 howItKilled = (proc(victim: OB1) =
                   echo "Obi Wan Kenobi was Killed")) =
      
      howItKilled ob1
    
    method kill*(self: Hero, yoda: Yoda,
                 howItKilled = (proc(victim: Yoda) =
                   echo "Obi Wan Kenobi was Killed")) =
      
      howItKilled yoda
    
    
    
    #main.nim
    
    import heroes
    import jedi
    
    let
      darthVader = new Hero
      yoda = new Yoda
    
    try:
      darthVader.kill(cast[Hero](yoda), howItKilled=nil)
    except ImplementationError:
      echo getCurrentExceptionMsg()
    
    darthVader.kill yoda  # call with default defined closure
    darthVader.kill(yoda, howItKilled=(proc(yoda: Yoda) = echo "Yoda may not be 
killed"))
    

Reply via email to