I am struggling to do a comparison of objects without the compiler complaining. I know how to do this in C#, but not Fantom (new to Fantom); please help.
class Boomtown {
// Objects entered into foo are classes which inherit Foo class
Foo?[] foo := Foo?[,].fill(8,null)
internal Future? doSomething( Foo something ) {
// Does foo have items?
haveFoo := foo.findAll | v | { v != null }
if( haveFoo.size > 0 ) {
// This where I start to get lost
foundDiff := haveFoo.each | v | {
if( v isnot something ) { // Compiler doesn't like this: Unknown type 'something'
return true
}
}
...
}
}
Thanks in advance for any help.
SlimerDudeWed 22 Jul 2020
Hi Dan B,
You didn't say what the compiler errors were - but I found a few - a couple being:
it's Foo?[,].fill(null, 8) - not Foo?[,].fill(8,null)
And something would need to be a defined class like Foo.
For what you want, I think you'll need to use List.all() or List.any(), like this:
class Boomtown {
// Objects entered into foo are classes which inherit Foo class
Foo?[] foo := Foo?[,].fill(null, 8)
internal Obj? doSomething( Foo something ) {
// Does foo have items?
haveFoo := foo.all |v| { v == null || v is Foo }
echo(haveFoo)
return null
}
}
class Foo { }
Dan BWed 22 Jul 2020
I just tried the following; which results in the same compiler error.
I don't think I have asked the question correctly or provided the correct background.
We have the following classes
MicroTask: very basic just holds an integer 0 to 7
AmAcWrTask: Inherits MicroTask (i.e. class AmAcWrTasl : MicroTask)
AutoConfigTask: Inherits AmAcWrTask
AutoMatchTask: Inherits AmAcWrTask
WireResistanceTask: Inherits AmAcWrTask
SyncConfigTask: Inherits MicroTask
Then in another class
private MicroTask?[] activeMicroTasks := MicroTask?[,].fill(null, 8)
private MicroTask?[] delayedMicroTasks := MicroTask?[,].fill(null, 8)
// Run a task for a particular micro
internal Future? runMicroTask( MicroTask task, Bool checked := true, Bool autoStatus := true ) {
// Input arg "task" can be one of: AutoConfigTask, AutoMatchTask, SyncConfigTask, or WireResistanceTask
// Class variable "activeMicroTasks" will contain the "task" at the correct index later in this function.
// I am trying to detect when runMicroTask is called with a different task type than what task type(s)
// is contained in activeMicroTasks.
// If it is different the incoming task is placed in delayedMicroTasks, to be run later
...
}
The type checking in the background function works as expected.
// Background function, runs periodically
Void backgrouFunc() {
...
else {
// SAGE-1907: Maestro fails to send POST to start WR
haveActive := activeMicroTasks.findAll | v | { v != null }
haveDelayed := delayedMicroTasks.findAll | v | { v != null }
// Do we have any task that were delayed?
if( ( haveActive.size == 0 ) && ( haveDelayed.size > 0 ) ) {
Device.log.info( "[BG Thread] delayedMicroTasks: $delayedMicroTasks ")
delayedMicroTasks.each | MicroTask? m, Int j | {
// Mark it as null so we don't repeat it
delayedMicroTasks[ j ] = null
if( m is SyncMicroConfigTask ){
syncConfigMicros.add( j )
}
else if( m is AutoMatchTask ) {
autoMatchMicros.add( j )
}
else if( m is AutoConfigTask ) {
autoConfigMicros.add( j )
}
else if( m is WireResistanceTask ) {
Device.log.info( "[BG Thread] Adding delayed WR task for micro $j" )
wireResistanceMicros.add( j )
}
}
}
}
}
Dan BWed 22 Jul 2020
My solution. Was hoping for something a little more elegant
haveSync := activeMicroTasks.any | v | { v != null && v is SyncMicroConfigTask }
haveAC := activeMicroTasks.any | v | { v != null && v is AutoConfigTask }
haveAM := activeMicroTasks.any | v | { v != null && v is AutoMatchTask }
haveWR := activeMicroTasks.any | v | { v != null && v is WireResistanceTask }
// There is active tasks. Now check the type of active
// versus the requested (passed in) task
if( ( ( haveSync ) && ( task isnot SyncMicroConfigTask ) ) ||
( ( haveAC ) && ( task isnot AutoConfigTask ) ) ||
( ( haveAM ) && ( task isnot AutoMatchTask ) ) ||
( ( haveWR ) && ( task isnot WireResistanceTask ) ) )
{
canRun = false
}
else
{
canRun = true
}
SlimerDudeWed 22 Jul 2020
Was hoping for something a little more elegant
I dunno, that logic looks kinda complicated to me...
I mean, if you wanted to reduce the code, you could loop over the types:
But then I'd argue you loose a lot of readability as to what the code actually does... time to break out the unit tests!
Dan BWed 22 Jul 2020
Yes, I like the readability of my solution
Dan BFri 24 Jul 2020
Actually Jeremy provided a clean and readable solution.
haveActive := activeMicroTasks.findAll | v | { v != null }
canRun := haveActive.any{ it.typeof.fits( task.typeof ) }
brianFri 24 Jul 2020
In the upcoming release there is also a findNotNull method. But one method that will filter out nulls and find a specific type is the sys::List.findType method:
Dan B Wed 22 Jul 2020
I am struggling to do a comparison of objects without the compiler complaining. I know how to do this in C#, but not Fantom (new to Fantom); please help.
Thanks in advance for any help.
SlimerDude Wed 22 Jul 2020
Hi
Dan B
,You didn't say what the compiler errors were - but I found a few - a couple being:
Foo?[,].fill(null, 8)
- notFoo?[,].fill(8,null)
foundDiff := haveFoo.each
-each()
doesn't return anythingAnd
something
would need to be a defined class likeFoo
.For what you want, I think you'll need to use List.all() or List.any(), like this:
Dan B Wed 22 Jul 2020
I just tried the following; which results in the same compiler error.
Dan B Wed 22 Jul 2020
SlimerDude, thanks for the reply. I posted my second without first refreshing the page. I will try your solution.
The foo init was my mistake in creating the question. The real code has the correct int. I was trying to keep my question generic
Dan B Wed 22 Jul 2020
I don't think I have asked the question correctly or provided the correct background.
We have the following classes
Then in another class
The type checking in the background function works as expected.
Dan B Wed 22 Jul 2020
My solution. Was hoping for something a little more elegant
SlimerDude Wed 22 Jul 2020
I dunno, that logic looks kinda complicated to me...
I mean, if you wanted to reduce the code, you could loop over the types:
But then I'd argue you loose a lot of readability as to what the code actually does... time to break out the unit tests!
Dan B Wed 22 Jul 2020
Yes, I like the readability of my solution
Dan B Fri 24 Jul 2020
Actually Jeremy provided a clean and readable solution.
brian Fri 24 Jul 2020
In the upcoming release there is also a findNotNull method. But one method that will filter out nulls and find a specific type is the
sys::List.findType
method:Which I think will collapse that to one line: