Skip to content

Instantly share code, notes, and snippets.

@jacoby
Created January 19, 2021 21:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jacoby/99ec52cc82c578c030d4ae7a15974828 to your computer and use it in GitHub Desktop.
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.
#!/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