I'm looking to possibly help update the File::HomeDir module which was never finished. While inspecting it, I noticed that stubbed out methods were causing infinite loops:
In the File::HomeDir
role:
unit class File::HomeDir;
use File::HomeDir::Win32;
use File::HomeDir::MacOSX;
use File::HomeDir::Unix;
my File::HomeDir $singleton;
method new
{
return $singleton if $singleton.defined;
if $*DISTRO.is-win {
$singleton = self.bless does File::HomeDir::Win32;
} elsif $*DISTRO.name.starts-with('macos') {
$singleton = self.bless does File::HomeDir::MacOSX;
} else {
$singleton = self.bless does File::HomeDir::Unix;
}
return $singleton;
}
method my-home {
return File::HomeDir.new.my-home;
}
method my-desktop {
return File::HomeDir.new.my-desktop;
}
<snip>
In the File::HomeDir::MacOSX
module:
use v6;
unit role File::HomeDir::MacOSX;
method my-home {
# Try HOME on every platform first, because even on Windows, some
# unix-style utilities rely on the ability to overload HOME.
return %*ENV<HOME> if %*ENV<HOME>.defined;
return;
}
method my-desktop {
!!!
}
<snip>
With this code, calling say File::HomeDir.my-desktop;
results in an infinite loop.
This module was first written about 5 1/2 years ago. I'm assuming it worked at the time. But it appears now that if a role method has a listop operator, it causes the parent's class to be called which then called the role method which then calls the parent class, etc.
I'd do it like this, staying close to the original design:
role File::HomeDir::Win32 {
method my-home() { dd }
method my-desktop() { dd }
}
role File::HomeDir::MacOSX {
method my-home() { dd }
method my-desktop() { dd }
}
role File::HomeDir::Unix {
method my-home() { dd }
method my-desktop() { dd }
}
class File::HomeDir {
my $singleton;
# Return singleton, make one if there isn't one already
sub singleton() {
without $singleton {
$_ = File::HomeDir but $*DISTRO.is-win
?? File::HomeDir::Win32
!! $*DISTRO.name.starts-with('macos')
?? File::HomeDir::MacOSX
!! File::HomeDir::Unix;
}
$singleton
}
method my-home() { singleton.my-home }
method my-desktop() { singleton.my-desktop }
}
File::HomeDir.my-home;
File::HomeDir.my-desktop;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With