Created
January 19, 2021 21:35
-
-
Save jacoby/99ec52cc82c578c030d4ae7a15974828 to your computer and use it in GitHub Desktop.
This is my commented understanding of the suggestions, after it was made to work. Wondering if I should blog this.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env perl | |
use strict; | |
use warnings; | |
# This must come before `main`. Most Moose uses will be in a | |
# separate module, but for the Perl Challenge code, I try to | |
# keep in all in one file to avoid issues. | |
package Stack; | |
use Moose; | |
use List::Util qw{}; # explicitly imports nothing | |
use feature qw{ say signatures }; # usually I add state, just so | |
# I don't forget it, but I'm not | |
# using it, so it's not here. | |
no warnings 'experimental'; # <-- THIS MUST BE AFTER use MOOSE | |
# OR warnings will still come | |
# consider constants. Specifically | |
# use constant ARRAY => []; | |
# ARRAY isn't an array, but a reference to an array, and thus | |
# I can push and pop and shift and unshift and delete and other | |
# array methods on it. I just can't make it point to another | |
# reference. | |
# Same as here. is => 'ro' just means I can't change array refs | |
# midstream | |
# _stack IS an arrayref. It has the traits of an Array, as hidden | |
# in the docs | |
# https://metacpan.org/pod/Moose::Meta::Attribute::Native::Trait::Array | |
# from traits, we get what it "handles", which are built in object | |
# methods. push exists as with standard arrays. pop exists as with | |
# standard arrays. top (what's at the top of the stack) renames | |
# get. I mean, it's not identical behavior but I'll be happy with | |
# it and not send it an input value | |
# and elements lists all of the entries in the array. This is not | |
# default behavior. We want it so we can test. So we prepend an | |
# underline and alias _all | |
has '_stack' => ( | |
is => 'ro', | |
isa => 'ArrayRef', | |
builder => '_build__stack', | |
traits => ['Array'], | |
handles => { | |
push => 'push', | |
pop => 'pop', | |
top => 'get', | |
_all => 'elements', | |
}, | |
); | |
# simply a function that returns an empty array | |
# we could have had builder => {[]}, but evidently | |
# builder => [] will just make things explode. | |
sub _build__stack { [] } | |
# this is the kind of OOP stuf that, once I started seeing it, | |
# seemed like magic. we get before, after and around. | |
# before simply runs *before* a function is run | |
# after simply runs *after* a function is run | |
# around has more magic. It interrupts and wraps the | |
# function named. here it's interrupting the top function | |
# I complained about, strips any arguments I might have | |
# wanted to throw at it and specifies the last element, | |
# the top of the stack. | |
around 'top' => sub ( $orig, $self ) { | |
return $self->$orig(-1); | |
}; | |
# all, as mentioned, is a function meant to allow us to look | |
# into the stack and see all the things stacked, so we know | |
# everything is as it should be. Rather than try to poke | |
# at the internals, it uses _all to get the list, and top | |
# to see the top of the stack. If it returns undef, there's | |
# nothing to say, so it doesn't | |
sub all ($self) { | |
say join " ", ' --', $self->_all | |
if defined $self->top; | |
} | |
# because it has to be named "min", we can't just import | |
# min from List::Util, but instead have to Long::Name::subroutine | |
# it. It's the same, except we use _all to get the list instead | |
# of interacting with the guts directly | |
sub min ($self) { | |
return List::Util::min $self->_all; | |
} | |
# this is boilerplate that keeps Moose load and/or run times | |
# from exploding. I don't know the magic behind this. | |
no Moose; | |
__PACKAGE__->meta->make_immutable; | |
package main; | |
# besides being moved down, this is exactly like my Challenge 95 | |
# code. | |
use feature qw{ say signatures state }; | |
no warnings qw{ experimental }; | |
# I use `say` instead of `print` because the newlines | |
# improve readability in the output | |
my $stack = Stack->new; | |
$stack->push(2); | |
$stack->push(-1); | |
$stack->push(0); | |
$stack->all; # 2, -1, 0 | |
$stack->pop; # removes 0 | |
$stack->all; | |
say $stack->top; # prints -1 | |
$stack->push(0); | |
$stack->all; | |
say $stack->min; # prints -1 | |
say 'DONE'; | |
exit; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment