Skip to content

Remove unnecessary FileDescriptor overrides#1129

Merged
jcazevedo merged 6 commits into
masterfrom
simplify-fds-impls
Jul 23, 2026
Merged

Remove unnecessary FileDescriptor overrides#1129
jcazevedo merged 6 commits into
masterfrom
simplify-fds-impls

Conversation

@bdmendes

Copy link
Copy Markdown
Contributor

These operations are safe to perform at the base. There is no need to repeat them in implementations – they were sometimes slightly more efficient (e.g. not allocating intermediate wrappers while descending through child directories) but I don't think that is significant enough to maintain more code.

Does this change relate to existing issues or pull requests?

Opportunistic change after #1128.

Does this change require an update to the documentation?

No.

How has this been tested?

I am relying on the soundness of the parent and child implementations.

@bdmendes bdmendes self-assigned this Jul 20, 2026
@bdmendes
bdmendes force-pushed the simplify-fds-impls branch 2 times, most recently from e9536ca to c6e905c Compare July 20, 2026 17:00
@bdmendes
bdmendes requested a review from jcazevedo July 21, 2026 10:40
@bdmendes
bdmendes marked this pull request as ready for review July 21, 2026 10:40
Base automatically changed from sftp-rename to master July 22, 2026 13:31

@jcazevedo jcazevedo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for this!

I think this change makes sense, but I would still keep open the opportunity for implementations to override specific methods (i.e. remove the finals), particularly with FileDescriptor not being sealed.

* an iterator with the lines of this file.
*/
def lines(): Iterator[String] = Source.fromInputStream(stream()).getLines()
final def lines(): Iterator[String] = Source.fromInputStream(stream()).getLines()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think it's still reasonable to give the option of implementations to redefine this, no?

Suggested change
final def lines(): Iterator[String] = Source.fromInputStream(stream()).getLines()
def lines(): Iterator[String] = Source.fromInputStream(stream()).getLines()

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Please see 19f3ab3.

* the new file descriptor with the updated path
*/
def /(name: String): Self = child(name)
final def /(name: String): Self = child(name)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think it's still reasonable to give the option of implementations to redefine this, no?

Suggested change
final def /(name: String): Self = child(name)
def /(name: String): Self = child(name)

* the new file descriptor with the updated path
*/
def children(names: String*): Self =
final def children(names: String*): Self =

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think it's still reasonable to give the option of implementations to redefine this, no?

Suggested change
final def children(names: String*): Self =
def children(names: String*): Self =

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Please see 1549f5e.

* the new file descriptor with the updated path
*/
def cd(pathString: String): Self = {
final def cd(pathString: String): Self = {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think it's still reasonable to give the option of implementations to redefine this, no?

Suggested change
final def cd(pathString: String): Self = {
def cd(pathString: String): Self = {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Please see d5d001e.

* a new file descriptor pointing to a sibling of the current file descriptor
*/
def sibling(name: String): Self = sibling(_ => name)
final def sibling(name: String): Self = sibling(_ => name)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think it's still reasonable to give the option of implementations to redefine this, no?

Suggested change
final def sibling(name: String): Self = sibling(_ => name)
def sibling(name: String): Self = sibling(_ => name)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Please see 1549f5e.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please see 1549f5e.

I don't think this commit is removing the final keyword. Intended?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Meant to comment on the inner sibling. I'll argue for keeping the final for the adapter methods next.

* a new file descriptor pointing to a sibling of the current file descriptor
*/
def sibling(f: String => String): Self = parent().child(f(name)).asInstanceOf[Self]
final def sibling(f: String => String): Self = parent().child(f(name)).asInstanceOf[Self]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think it's still reasonable to give the option of implementations to redefine this, no?

Suggested change
final def sibling(f: String => String): Self = parent().child(f(name)).asInstanceOf[Self]
def sibling(f: String => String): Self = parent().child(f(name)).asInstanceOf[Self]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Please see 19f3ab3.

*/
def cd(pathString: String): Self = {
final def cd(pathString: String): Self = {
pathString.split("/").toList.foldLeft(this.asInstanceOf[Self]) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

All the implementations of this were trimming the individual splits. I can't recall why. Maybe we were just being overcautious for malformed inputs. That being said, it might not be a bad idea to keep the trimming in the overarching implementation for the time being.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Brought back the trimming in 1549f5e.

protected def duplicate(elements: List[String]): Self

def parent(n: Int = 1): Self =
final def parent(n: Int = 1): Self =

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think it's still reasonable to give the option of implementations to redefine this, no?

Suggested change
final def parent(n: Int = 1): Self =
def parent(n: Int = 1): Self =

this.duplicate(elements = elements.dropRight(n))

def child(name: String): Self =
final def child(name: String): Self =

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think it's still reasonable to give the option of implementations to redefine this, no?

Suggested change
final def child(name: String): Self =
def child(name: String): Self =

@bdmendes
bdmendes force-pushed the simplify-fds-impls branch from 3086784 to 19f3ab3 Compare July 23, 2026 09:59
@bdmendes

Copy link
Copy Markdown
Contributor Author

I agree that, in some cases, it might make sense to keep the possibility for implementations to override as needed for performance. However, in the cases of / (alias to child) and the sibling adapter I don't think it is relevant. Let me know.

@bdmendes
bdmendes requested a review from jcazevedo July 23, 2026 10:44
Comment thread modules/io/src/main/scala/com/kevel/apso/io/FileDescriptor.scala Outdated
Co-authored-by: João Costa <jdpc557@gmail.com>
@jcazevedo

Copy link
Copy Markdown
Member

I agree that, in some cases, it might make sense to keep the possibility for implementations to override as needed for performance. However, in the cases of / (alias to child) and the sibling adapter I don't think it is relevant. Let me know.

Fair enough.

@jcazevedo jcazevedo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thank you!

@jcazevedo
jcazevedo merged commit e2dcf8c into master Jul 23, 2026
10 checks passed
@jcazevedo
jcazevedo deleted the simplify-fds-impls branch July 23, 2026 11:07
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