| Calling base class constructor 2012-05-03 18:36:34 | |
|---|---|
|
Vladar
|
I tried to find a way of calling base class constructor with Nimrod classes like I used to do in other object-oriented languages, in Python for example:class ClassA: def __init__(self): self.x = 1 class ClassB(ClassA): def __init__(self): ClassA.__init__(self) self.y = 1 b = ClassB() print "x =", b.x, "y =", b.y output: x = 1 y = 1 So for now I made this: type # parent object PObjectA = ref TObjectA TObjectA = object of TObject x: int # child object PObjectB = ref TObjectB TObjectB = object of TObjectA y: int # parent object constructor proc newObjectA(child: PObjectA = nil): PObjectA = if child == nil: new(result) # if creates a new object else: result = child # if ref to child provided # init object fields result.x = 1 # child object constructor proc newObjectB(child: PObjectB = nil): PObjectB = if child == nil: new(result) else: result = child discard newObjectA(result) # calling parent object consructor # init object fields result.y = 2 var b: PObjectB = newObjectB() echo("x=", b.x, " y=", b.y) output: x=1 y=2 But don't I miss some easier way to do this? |
| Re: Calling base class constructor 2012-05-03 21:21:19 | |
|---|---|
|
Araq
|
I'd use this instead:type PObjectA = ref TObjectA TObjectA = object of TObject x: int PObjectB = ref TObjectB TObjectB = object of TObjectA y: int proc initA(a: PObjectA) = a.x = 1 # parent object constructor proc newObjectA(): PObjectA = new(result) initA(result) # child object constructor proc newObjectB(): PObjectB = new(result) initA(result) # init object fields result.y = 2 var b = newObjectB() echo("x=", b.x, " y=", b.y) |
| Related question 2012-05-12 18:54:00 | |
|---|---|
|
Vladar
|
Thanks for reply. Also I've got a related question. When I try to call base class method I get segmentation fault. It seems that this is not the right way to do it: type PObjectA = ref TObjectA TObjectA = object of TObject PObjectB = ref TObjectB TObjectB = object of TObjectA method update(obj: PObjectA) = echo("update parent") method update(obj: PObjectB) = #PObjectA(obj).update() # This is causes a segfault echo("update child") proc newObjectA(): PObjectA = new(result) proc newObjectB(): PObjectB = new(result) var x: PObjectA = newObjectB() x.update() |
| Re: Related question 2012-05-12 21:55:58 | |
|---|---|
|
Araq
|
method update(obj: PObjectB) = PObjectA(obj).update()Your explicit type conversion does not inhibit dynamic binding so you create an endless recursion here, causing a stack overflow and thus a segfault. Again, to get "super"-like functionality, you need to use a helper proc: type PObjectA = ref TObjectA TObjectA = object of TObject PObjectB = ref TObjectB TObjectB = object of TObjectA proc updateA(obj: PObjectA) = echo "update parent" method update(obj: PObjectA) = updateA(obj) method update(obj: PObjectB) = updateA(obj) proc newObjectA(): PObjectA = new(result) proc newObjectB(): PObjectB = new(result) var x: PObjectA = newObjectB() x.update() |
| Re: Related question 2012-05-12 22:09:28 | |
|---|---|
|
Vladar
|
Hm… A little messy but works as intended. Thanks again! |
| Re: Related question 2012-05-14 07:31:54 | |
|---|---|
|
leledumbo
|
> Your explicit type conversion does not inhibit dynamic binding so you create an endless recursion here, causing a stack overflow and thus a segfault Should a thing like this be detected at compile time? Or at least raise another exception other than SIGSEGV? |
| Re: Related question 2012-05-16 08:07:23 | |
|---|---|
|
Araq
|
Detecting this at compile time seems hard. I'm still thinking about how to improve it. Detecting stack overflows at runtime properly is also non-trivial; previous attempts never really worked: It's hard (but not impossible) to call a stack overflow handler when there is no space left in the stack. |
| Re: Related question 2012-05-30 20:37:33 | |
|---|---|
|
renoX
|
Hello, I just discovered Nimrod and I like many aspects of it, but it seems that object oriented code will be very verbose if this example is any indication: I think that the equivalent code in Scala would be much, much shorter (Python's initial example is already terser than Nimrod).. I'm a bit worried by this aspect of Nimrod.. BR, renoX |
| Re: Related question 2012-05-30 22:01:30 | |
|---|---|
|
Araq
|
It's possible to design a 'class' macro but nobody ever wrote it. # implementation left as an exercise for the reader import classes class MyClass(refsemantics): proc init() = x = 3 # 'class' could make implicit field definitions possible method doIt() = # aka 'virtual' echo "do it" |
| Re: Related question 2012-06-04 07:48:05 | |
|---|---|
|
renoX
|
> It's possible to design a 'class' macro but nobody ever wrote it. To study what would be a good design, why not? But for a "base" feature in the end, it must be built-in in the language otherwise it will make debugging more difficult (thinking long term with a "native" compiler). |