-
Notifications
You must be signed in to change notification settings - Fork 1
/
QuoteCC.pm
181 lines (135 loc) · 4.86 KB
/
QuoteCC.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
package App::QuoteCC;
use perl5i::latest;
use Moose;
use namespace::clean -except => 'meta';
with qw/ MooseX::Getopt::Dashes /;
has help => (
traits => [ qw/ Getopt / ],
cmd_aliases => 'h',
cmd_flag => 'help',
isa => 'Bool',
is => 'ro',
default => 0,
documentation => 'This help message',
);
has input => (
traits => [ qw/ Getopt / ],
cmd_aliases => 'i',
cmd_flag => 'input',
isa => 'Str',
is => 'ro',
documentation => 'The quotes file to compile from. - for STDIN',
);
has input_format => (
traits => [ qw/ Getopt / ],
cmd_aliases => 'I',
cmd_flag => 'input-type',
isa => 'Str',
is => 'ro',
documentation => 'The format of the input quotes file. Any App::QuotesCC::Input::*',
);
has output => (
traits => [ qw/ Getopt / ],
cmd_aliases => 'o',
cmd_flag => 'output',
isa => 'Str',
is => 'ro',
default => '-',
documentation => 'Where to output the compiled file, - for STDOUT',
);
has output_format => (
traits => [ qw/ Getopt / ],
cmd_aliases => 'O',
cmd_flag => 'output-type',
isa => 'Str',
is => 'ro',
documentation => 'The format of the output file. Any App::QuotesCC::Output::*',
);
sub run {
my ($self) = @_;
my $dynaload = sub {
my ($vars, $new_args) = @_;
my ($self_method_type, $class_type) = @$vars;
my %args = %$new_args;
my $x_class_short = $self->$self_method_type;
my $x_class = "App::QuoteCC::${class_type}::" . $x_class_short;
$x_class->require;
my $obj = $x_class->new(%args);
return $obj;
};
my $input = $dynaload->(
[ qw/ input_format Input / ],
{ file => $self->input },
);
my $quotes = $input->quotes;
my $output = $dynaload->(
[ qw/ output_format Output / ],
{
file => $self->output,
quotes => $quotes,
},
);
$output->output;
return;
}
__PACKAGE__->meta->make_immutable;
=encoding utf8
=head1 NAME
App::QuoteCC - Take a quote file and emit a standalone program that spews a random quote
=head1 SYNOPSIS
Compile a quotes file to a stand-alone binary:
curl http://v.nix.is/~failo/quotes.yml | quotecc -i - -I YAML -o - -O C | gcc -x c -o failo-wisdom -
curl http://www.trout.me.uk/quotes.txt | quotecc -i - -I Fortune -o - -O C | gcc -x c -o perl-wisdom -
Or to a fast stand-alone minimal Perl script:
curl http://v.nix.is/~failo/quotes.yml | quotecc -i - -I YAML -o failo-wisdom.pl -O Perl
curl http://www.trout.me.uk/quotes.txt | quotecc -i - -I Fortune -o perl-wisdom.pl -O Perl
See how small they are:
$ du -sh *-wisdom*
56K failo-wisdom
44K failo-wisdom.pl
80K perl-wisdom
76K perl-wisdom.pl
Emit a random quote with the C program:
time (./failo-wisdom && ./perl-wisdom)
Support Batman - vote for the British National Party
< dha> Now all I have to do is learn php
<@sungo> it's easy.
<@sungo> take your perl knowledge. now smash it against child pornography
real 0m0.004s
user 0m0.000s
sys 0m0.008s
Or with the Perl program:
$ time (perl failo-wisdom.pl && perl perl-wisdom.pl)
I just see foreign words like private public static void feces implements shit extending penis
<@pndc> Imagine if cleaners were treated like sysadmins. "I've just
pissed all over the office floor; it's the cleaner's fault."
real 0m0.022s
user 0m0.012s
sys 0m0.004s
Emit all quotes:
./failo-wisdom --all > /tmp/quotes.txt
Emit quotes to interactive shells on login, in F</etc/profile>:
# spread failo's wisdom to interactive shells
if [[ $- == *i* ]] ; then
failo-wisdom
fi
=head1 DESCRIPTION
I wrote this program because using L<fortune(1)> and Perl in
F</etc/profile> to emit a random quote on login was too slow. On my
system L<fortune(1)> can take ~100 ms from a cold start, although
subsequent invocations when it's in cache are ~10-20 ms.
Similarly using Perl is also slow, this is in the 80 ms range:
perl -COEL -MYAML::XS=LoadFile -E'@q = @{ LoadFile("/path/to/quotes.yml") }; @q && say $q[rand @q]'
Either way, when you have a 40 ms ping time to the remote machine
showing that quote is the major noticeable delay when you do I<ssh
machine>.
L<quotecc> solves that problem, showing a quote takes around 4 ms
now. That's comparable with any hello wold program in C that I
produce.
=head1 AUTHOR
E<AElig>var ArnfjE<ouml>rE<eth> Bjarmason <avar@cpan.org>
=head1 LICENSE AND COPYRIGHT
Copyright 2010 E<AElig>var ArnfjE<ouml>rE<eth> Bjarmason <avar@cpan.org>
This program is free software, you can redistribute it and/or modify
it under the same terms as Perl itself.
=cut