[Gambas-user] Inheriting, wrapping and casting

B Bruen bbruen at ...2308...
Fri Apr 18 02:19:36 CEST 2014


I don't believe there is a need for "castUp" as the object can be referenced as any parent type up the chain.

	Dim hChild as CChild
	Dim hParent as CParent

	hChild= New CChild
	hParent = hChild

However, there is a use for a generalised castDown method. We have quite a few situations when the exact "child-type" is unknown at the time the object is created, but we know that when the methods that create the object are complete then that specialisation will be resolved.  Particularly this happens with single pass parsers where the specialisation can't be resolved until some subsequent line of data is parsed. (A specific example, in many of the auction lists we receive, line N can be recognised as a new horse by virtue of the fact that the line begins "Lot [1-9]* " but the fact that it is a yearling or a mare or whatever is not disclosed until we get to line N+2 or N+3), 
As far as I know, something along the lines of 
	Dim hParent as CParent
	Dim hChild as CChild

	hParent = New CParent
	With hParent
		.set the property values as we know them initially
	End With
	...
	hChild=hParent  <-- This bit doesn't "work"
	hChild.someproperty = somenewdata

Here is how we do it, (which goes in the most ancestral class of the chain) (and appears to have worked OK for ~3 years):

'' Casts the current object as an instance of the **sNewClass** class. The 
''`new class must be a descendant of the current class.
Public Function Cast(sNewClass As String) As Object

  Dim hNew As Object
  Dim sSymbol As String
  
  hNew = Object.New(sNewClass)
  
 ' If morphing downwards, then the cast is allowed!
  If (Object.Is(hNew, Object.Type(Me))) Then Goto DO_CAST

' Check we are trying for a cast in the proper chain
  If Classes[sNewClass].Parent <> Object.Class(Me).Parent Then 
    Error.Raise(Subst("Illegal cast: &1 --/--> &2", Object.Type(Me), Object.Type(hNew)))
  Endif
  
DO_CAST:
  For Each sSymbol In Object.Class(Me).Symbols
    If sSymbol = "." Then Continue
    If Not Object.Class(hNew).Symbols.Exist(sSymbol) Then Continue
    If Object.Class(Me)[sSymbol].Kind = Class.Property Then
      If Not Object.Class(hNew)[sSymbol].ReadOnly Then
        Object.SetProperty(hNew, sSymbol, Object.GetProperty(Me, sSymbol))
      Endif
    Endif
  Next
  Return hNew

Catch
  Error Subst("&1\nERR: &2 (&3)\n&4\n&1\n", String$(40, "-"), Error.Text, Error.Code, Error.Backtrace.Join("\n"))
  Message.Error("General cast error! Check stderr output for details")

End


regards
Bruce

On Thu, 17 Apr 2014 21:13:41 +0200
Fabien Bodard <gambas.fr at ...626...> wrote:

> Well ... I'm surely not good as you are but I didn't understand the
> meanning of castup or down... What is it for ?
> Le 17 avr. 2014 21:02, "Bruno Félix Rezende Ribeiro" <oitofelix at ...3321.....> a
> écrit :
> 
> > Hello Gambas fellows!
> >
> > Suppose we are overriding the class 'Variant[]' to add the event
> > 'Update' which will be raised after the completion of any method which
> > could possibly modify the array structure.  In particular, we need
> > to override appropriately any function that happens to do so.  For
> > exposition purposes let's consider the 'Extract' function, which removes
> > one or more elements from the array and returns them.  It's signature
> > is as follow:
> >
> >   Public Function Extract(iStart As Integer, \
> >     Optional iLength As Integer) As Variant[]
> >
> > Our inherited class has, hence, to override this function with another
> > of the exact same signature, by Gambas' rules.  However, it doesn't
> > make sense to return an object of the base class, while the operation
> > is executed by a derived class over an object thereof.
> >
> > It seems there is no easy or natural way around it.  We could declare a
> > second extraction function for the derived class named after a different
> > symbol like "ExtractDerived", but we'd break the interface, what isn't
> > a desired outcome.
> >
> > Another approach would be to forget this particular base class and go
> > upwards until there is no possible conflicting functions and to inherit
> > from there, what happens to be in this case the immediate base class of
> > 'Variant[]' called "Array".  However, we'd have to re-implement large
> > portions of the 'Variant[]' class, that could otherwise be immediately
> > deployed if not by our particular design problem at hand.
> >
> > One last, and arguably more reasonable, approach is to give up the
> > syntactical native language's feature of inheritance --- and its useful
> > properties -- and to define a dedicated container base class, which
> > inherits from nowhere, semantically wrapping all functionality of the
> > class 'Variant[]'.  It'd work as a layer for accessing the underlying
> > variant array which would be stored in a private variable and isolated
> > from the outside world, i.e., not directly accessible by any property.
> > The only way to modify the array's content would be to use the
> > class' interface which would mimic that of 'Variant[]'.
> >
> > As we've seen, there is no way if not by modifications of the
> > interpreter's very core.  Thus, I'd like to know why Gambas enforces
> > the signature of functions onwards inherited classes.  If not by
> > technical reasons, but only for methodological consistency requirements,
> > I'd like to suggest that we make it, at least, allows to use the
> > inherited class in place of the parent class within method signatures.
> > Personally, I'd find yet more useful if there were no restriction at
> > all.
> >
> > A very interesting and useful feature, related but independent of this
> > suggestion, is that the interpreter could take care of casting objects
> > in both directions in an hierarchy of classes.  In order to accomplish
> > it, there would be introduced two special methods which would be
> > implemented in any class the programmer deems them meaningful and
> > useful: '_castUp' and '_castDown', for casting an object from the
> > inherited to the parent class, and from the parent to the inherited
> > class, respectively.  Being 'ThisClass' the inherited class and
> > 'UpClass' its parent, the special methods signatures would be:
> >
> > Static Public Function _castUp (hThisClass As ThisClass) As UpClass
> > Static Public Function _castDown (hUpClass As UpClass) As ThisClass
> >
> > The job of the interpreter would be to call these functions, in a
> > possible chain, to cast automatically upside or downside every time an
> > object of certain class is used in a context that requires an object of
> > another class but in the same hierarchy.
> >
> > What are your thoughts on that?
> >
> >
> > Thank you.
> >
> >
> > --
> >  ,= ,-_-. =.  Bruno Félix Rezende Ribeiro (oitofelix) [0x28D618AF]
> > ((_/)o o(\_)) There is no system but GNU;
> >  `-'(. .)`-'  GNU Linux-Libre is one of its official kernels;
> >      \_/      All software must be free as in freedom;
> >
> >
> > ------------------------------------------------------------------------------
> > Learn Graph Databases - Download FREE O'Reilly Book
> > "Graph Databases" is the definitive new guide to graph databases and their
> > applications. Written by three acclaimed leaders in the field,
> > this first edition is now available. Download your free book today!
> > http://p.sf.net/sfu/NeoTech
> > _______________________________________________
> > Gambas-user mailing list
> > Gambas-user at lists.sourceforge.net
> > https://lists.sourceforge.net/lists/listinfo/gambas-user
> >
> >
> ------------------------------------------------------------------------------
> Learn Graph Databases - Download FREE O'Reilly Book
> "Graph Databases" is the definitive new guide to graph databases and their
> applications. Written by three acclaimed leaders in the field,
> this first edition is now available. Download your free book today!
> http://p.sf.net/sfu/NeoTech
> _______________________________________________
> Gambas-user mailing list
> Gambas-user at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/gambas-user


-- 
B Bruen <bbruen at ...2308...>




More information about the User mailing list