Skip to content

Fix Overriding Immutable Variables #1453

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

olabusayoT
Copy link
Contributor

  • since we can no longer override immutable variables in Scala 3, we change Ustate's dataOutputStream field to be a private mutable variable with a setter and getter method

DAFFODIL-2975

Copy link
Member

@stevedlawrence stevedlawrence left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, just some comment about a different approach. I have no strong feeling about which approach to take so this is fine with me

@@ -423,6 +429,7 @@ final class UStateForSuspension(
areDebugging: Boolean
) extends UState(vbox, mainUState.diagnostics, mainUState.dataProc, tunable, areDebugging) {

setDataOutputStream(dataOutputStream)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This approach with getters/setters actually makes for a possible enhancement. I think that UStateForSuspension should never change the dataOutputStream. If that's true, you could change _dataOutputStream to protected, and then this this could be changed to something like

_dataOutputStream  = dataOutputSTream

And UStateForSuspension could overwrite setDataOutputStream to be something like

override def setDataOutputStream(...) = {
  Assert.invariantFailed("Should never change dataOutputStream on a suspension")
}

This effecively forces the dataOutputStream field to be unchanging for suspensions.

I don't think we necessarily need to do this as part of this PR (I'm not even sure it suspension DOSs never change), but this is a potential advantage for these kinds of setters/getters.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mbeckerle , can you confirm that UStateForSuspension shouldn't change the dataOutputStream?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is correct - once you have created a UStateForSuspension, lots of things are frozen there.

That said, the interplay and way output streams do this gradual double-buffering and collapsing of the buffers is quite tricky. It's the most complex part of the Daffodil runtime, so .... do I really know that there's no exception to this rule? No. We should try it.


def setDataOutputStream(dos: DirectOrBufferedDataOutputStream) = {
_dataOutputStream = dos
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that we don't necessarily need these getters/setters. We could make it so dataOutputStream is still public and initialize it to _, and then instead of overriding it, UStateForMain constructor would look like

dataOutputStream = DirectOrBufferedDataOutputStream(...)

and UStateForSuspension would look like

class UStateForSuspension(
  ...,
  suspensionDataOutputStream: DirectOrBufferedDataOutputStream,
  ...) {

  dataOutputStream = suspensionDataOutputSTream
}

That would avoid the needs for getters/setters and would make this a much smaller change. Though it does make it a but unsafer since it requires implementations to initialize it rather than the compiler forcing it to be overridden and initialized, but it's not a big deal for us since we only have these two classes.

Copy link
Contributor

@mbeckerle mbeckerle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1
I'm ok with this change. But we should definitely do the override of the setter behavior in the IO streams model to see if this no-writing the output data stream from UStateForSuspension in fact works.

- since we can no longer override immutable variables in Scala 3, we change Ustate's dataOutputStream field to be a private mutable variable with a setter and getter method
- ensure UStateForSuspension's dataOutputStream cannot be changed

DAFFODIL-2975
@olabusayoT olabusayoT force-pushed the daf-2975-fix-override-mutables-dataOutputStream branch from f8b5dc0 to 4e8ea4b Compare March 17, 2025 19:53
@olabusayoT olabusayoT merged commit abcfc29 into apache:main Mar 17, 2025
21 checks passed
@olabusayoT olabusayoT deleted the daf-2975-fix-override-mutables-dataOutputStream branch March 17, 2025 20:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants