Commit | Line | Data |
9d2a4940 |
1 | =pod |
2 | |
a2a19b0a |
3 | =head1 NAME |
4 | |
5 | Devel::REPL::Overview - overview of Devel::REPL. |
6 | |
7 | =head1 DESCRIPTION |
8 | |
9 | =head2 What is a console? How it can assist you? |
10 | |
8d5343b5 |
11 | Most modern languages have consoles. The console is an interactive tool |
a2a19b0a |
12 | that evaluates your input while you type it. |
13 | It gives you several advantages: |
14 | |
15 | =over 2 |
16 | |
17 | =item * |
18 | |
19 | Quickly test some thought or tricky expression |
20 | |
21 | =item * |
22 | |
23 | Run some code bigger than one line without a temporary file |
24 | |
25 | =item * |
26 | |
27 | Play around with libraries and modules |
28 | |
29 | =item * |
30 | |
31 | You can even call a console in your script and play around in script's context |
32 | |
33 | =back |
34 | |
0e0d2539 |
35 | For Ruby it would be irb, for Python is... python by itself and for perl... |
a2a19b0a |
36 | and there was nothing for perl (except that ugly perl -d -e "" and several |
8d5343b5 |
37 | failed projects) until L<Devel::REPL> was written by Matt S Trout (a.k.a. mst) |
a2a19b0a |
38 | from ShadowCatSystems L<http://www.shadowcatsystems.co.uk>. |
39 | |
a2a19b0a |
40 | =head2 Devel::REPL - the Perl console |
41 | |
a2a19b0a |
42 | REPL stands for Read, Evaluate, Print, Loop. |
43 | Lets install and try it. |
44 | |
45 | $ cpan Devel::REPL |
46 | |
47 | After installation you have a lot of new modules, |
48 | but the most interesting things are: |
49 | |
50 | =over 2 |
51 | |
52 | =item * |
53 | |
54 | Devel::REPL |
55 | A top level module. |
56 | |
57 | =item * |
58 | |
59 | re.pl |
60 | Wrapper script, running console. |
61 | |
62 | =back |
63 | |
64 | And a bunch of plugins (I'll describe them later). |
65 | In command line type: |
66 | |
67 | $ re.pl |
68 | |
69 | If everything is ok you'll see a prompt (underlined $). |
70 | That's it. You can start typing expressions. |
71 | |
72 | An example session: |
73 | |
74 | $ sub factorial { |
75 | |
76 | > my $number = shift; |
77 | |
78 | > return $number > 1 ? $number * factorial($number-1) : $number; |
79 | |
80 | > } |
81 | |
82 | $ factorial 1 # by the way, comments are allowed |
83 | |
84 | 1 # our return value |
85 | |
86 | $ factorial 5 |
87 | |
88 | 120 |
89 | |
90 | $ [1,2,3,4,5,6,7] |
91 | $ARRAY1 = [ |
92 | 1, |
93 | 2, |
94 | 3, # return values are printed with Data::Dumper::Streamer. |
95 | 4, # See Plugins section |
96 | 5, |
97 | 6, |
98 | 7 |
99 | ]; |
100 | |
101 | $ {apple=>1,fruit=>'apple',cart=>['apple','banana']} |
102 | $HASH1 = { |
103 | apple => 1, |
104 | cart => [ |
105 | 'apple', |
106 | 'banana' |
107 | ], |
108 | fruit => 'apple' |
109 | }; |
110 | |
111 | $ package MyPackage; # create a package |
112 | |
113 | $ sub say_hi { # define a sub |
114 | |
115 | > print "Hi!\n"; |
116 | |
117 | > } # statement is evaluated only after we've finished typing block. |
118 | # See Plugins section. |
119 | > __PACKAGE__ |
120 | MyPackage |
121 | > package main; |
122 | |
123 | > __PACKAGE_ |
124 | main |
125 | > MyPackage->say_hi |
126 | Hi! |
127 | 1 |
128 | $ |
129 | |
130 | |
131 | =head2 Control files a.k.a. I don't want to type it every time |
132 | |
8d5343b5 |
133 | L<Devel::REPL> has a control files feature. Control files are |
a2a19b0a |
134 | evaluated on session start in the same way as you would |
8d5343b5 |
135 | type them manually in the console. |
a2a19b0a |
136 | |
8d5343b5 |
137 | The default control file is located at F<$HOME/.re.pl/repl.rc>. |
a2a19b0a |
138 | |
139 | You can store there any statements you would normally type in. |
140 | |
8d5343b5 |
141 | I.e. my F<$HOME/.re.pl/repl.rc> has next lines: |
a2a19b0a |
142 | |
143 | use feature 'say'; # to don't write \n all the time |
144 | |
145 | use Data::Dumper; |
146 | |
147 | # pretty print data structures |
148 | sub pp { print Data::Dumper->Dump([@_]) } |
149 | |
150 | You can have multiple control files and they can be anywhere in the |
8d5343b5 |
151 | file system. To make F<re.pl> use some rc-file other than F<repl.rc>, |
a2a19b0a |
152 | call it like this: |
153 | |
154 | $ re.pl --rcfile /path/to/your/rc.file |
155 | |
8d5343b5 |
156 | If your rc-file is in F<$HOME/.re.pl> directory, you can omit the path: |
a2a19b0a |
157 | |
158 | $ re.pl --rcfile rc.file |
159 | |
160 | If you have rc-file with the same name in current directory |
161 | and you don't want to type path, you can: |
162 | |
163 | $ re.pl --rcfile ./rc.file |
164 | |
165 | =head2 I want it to bark, fly, jump and swim! or Plugins |
166 | |
0e0d2539 |
167 | Plugins extend functionality and change behavior of Devel::REPL. |
a2a19b0a |
168 | Bundled plugins are: |
169 | |
170 | =over 2 |
171 | |
172 | =item * |
173 | |
8d5343b5 |
174 | L<Devel::REPL::Plugin::History> |
a2a19b0a |
175 | No comments. Simply history. |
176 | |
177 | =item * |
178 | |
8d5343b5 |
179 | L<Devel::REPL::Plugin::!LexEnv> |
a2a19b0a |
180 | Provides a lexical environment for the Devel::REPL. |
181 | |
182 | =item * |
183 | |
8d5343b5 |
184 | L<Devel::REPL::Plugin::DDS> |
a2a19b0a |
185 | Formats return values with Data::Dump::Streamer module. |
186 | |
187 | =item * |
188 | |
8d5343b5 |
189 | L<Devel::REPL::Plugin::Packages> |
a2a19b0a |
190 | Keeps track of which package your're in. |
191 | |
192 | =item * |
193 | |
8d5343b5 |
194 | L<Devel::REPL::Plugin::Commands> |
a2a19b0a |
195 | Generic command creation plugin using injected functions. |
196 | |
197 | =item * |
198 | |
8d5343b5 |
199 | L<Devel::REPL::Plugin::MultiLine::PPI> |
a2a19b0a |
200 | Makes Devel::REPL read your input until your block |
201 | is finished. What does this means: you can type a part of a block |
202 | on one line and second part on another: |
203 | |
204 | $ sub mysub { |
205 | |
206 | > print "Hello, World!\n"; ## notice prompt change |
207 | |
208 | > } |
209 | |
210 | $ mysub |
211 | Hello, World! |
212 | 1 |
213 | $ |
214 | |
215 | but this *doesn't* mean you can print sub name or identifier |
216 | on several lines. Don't do that! It won't work. |
217 | |
a2a19b0a |
218 | =back |
219 | |
220 | There are lots of contributed plugins you can find at CPAN. |
221 | |
222 | =head1 Profiles |
223 | |
8d5343b5 |
224 | If plugins change and extend functionality of L<Devel::REPL>, profiles |
a2a19b0a |
225 | are changing your environment (loaded plugins, constants, subs and etc.). |
226 | |
8d5343b5 |
227 | For example, the Minimal profile, L<Devel::REPL::Profile::Minimal>: |
a2a19b0a |
228 | |
584978c9 |
229 | package Devel::REPL::Profile::Minimal; |
a2a19b0a |
230 | |
231 | use Moose; ### advanced OOP system for Perl |
232 | |
233 | ### keep those exports/imports out of our namespace |
aa8b7647 |
234 | use namespace::autoclean; |
a2a19b0a |
235 | |
236 | with 'Devel::REPL::Profile'; ## seem perldoc Muse |
237 | |
238 | sub plugins { ### plugins we want to be loaded |
239 | qw(History LexEnv DDS Packages Commands MultiLine::PPI); |
240 | } |
241 | |
242 | ### the only required sub for profile, |
243 | ### it is called on profile activation |
244 | sub apply_profile { |
245 | my ($self, $repl) = @_; |
afc8677b |
246 | ### $self - no comments, $repl - current instance of Devel::REPL |
a2a19b0a |
247 | |
248 | $repl->load_plugin($_) for $self->plugins; ### load our plugins |
249 | } |
250 | |
251 | 1; |
252 | |
8d5343b5 |
253 | There is also the L<StandardDevel::REPL::Profile::Standard> profile, which contains a number of optional (yet |
584978c9 |
254 | very useful) features. |
255 | |
8d5343b5 |
256 | To enable some profile use the C<--profile> switch: |
a2a19b0a |
257 | |
258 | $ re.pl --profile SomeProfile |
259 | |
584978c9 |
260 | Alternatively, you can set the environment variable C<DEVEL_REPL_PROFILE> to |
261 | C<SomeProfile>, or set the C<profile> key in your C<rcfile> (see |
262 | L<Devel::REPL> for more information). |
263 | |
8d5343b5 |
264 | =head1 SEE ALSO |
265 | |
f4d48832 |
266 | =for :list |
267 | * L<Devel::REPL> |
268 | * L<Devel::REPL::Plugin> |
269 | * L<Devel::REPL::Profile> |
270 | * L<Reply> |
a2a19b0a |
271 | |
8d5343b5 |
272 | =cut |