If I define this Fantom class
const class Mixed
{
const Int whole
const Int numerator
const Int denominator
const | -> Int[]| convertToFrac
new make( |This| func ) { func( this ) }
}
And I want to create an instance defining the convertToFrac function, like this:
class Example
{
Void main( Str args )
{
mixed := Mixed {
whole = 2
numerator = 3
denominator = 8
convertToFrac = |->Int[]| {
return [ whole * denominator + numerator, denominator ]
}
}
}
}
The compiler complains saying:
Unknown variable 'numerator'
Unknown variable 'denominator'
Unknown variable 'whole'
Is there any way to refer to the object "mixed" being created from within the function "convertToFrac", also being defined, without passing the "mixed" object as a parameter of the function?
If I prepend each variable with "mixed", like so:
return [ mixed.whole * mixed.denominator + mixed.numerator, mixed.denominator ]
The compiler complains: Unknown variable 'mixed'
.
Using this.whole
doesn't make sense as it refers to the Example class.
Using it.whole
doesn't make sense either as it refers to the Function.
Can anyone please suggest the way to access the "mixed" object from within the "convertToFrac" function?
As you correctly assessed, the issue is that you're using an it-block
inside an it-block
, and because you're using an implicit it
(i.e. you're don't have any it
qualifiers) there is confusion as to what's being referenced.
I'll write out the it
qualifiers out long hand so you can see what's going on:
mixed := Mixed {
// 'it' is the Mixed instance
it.whole = 2
it.numerator = 3
it.denominator = 8
it.convertToFrac = |->Int[]| {
// 'it' is now the func param
// 'it.whole' doesn't exist, because there is no func param
return [ it.whole * it.denominator + it.numerator, it.denominator ]
}
}
Your idea of using the mixed
variable qualifier was a good one but, unfortunately, whilst processing the ctor the mixed
variable hasn't been created yet so can't be referenced.
But you can create your own mixed
variable in the it-block, and the following compiles and runs quite happily:
mixed := Mixed {
// 'mixed' doesn't exist here yet, because we're still creating a value to assign to it
it.whole = 2
it.numerator = 3
it.denominator = 8
// assign `it` to our own `mixed` variable
mixed := it
it.convertToFrac = |->Int[]| {
// use our own `mixed` variable
return [ mixed.whole * mixed.denominator + mixed.numerator, mixed.denominator ]
}
}