| Perl | Emacs Lisp | |
|---|---|---|
| Basic output |
print STDERR "A message for the user\n"; print STDOUT "Some of the real output\n"; |
(message "A message for the user") (insert "Some of the real output") |
| Formatted strings | $output = sprintf("%s occurs %d times", $string, $number); |
(setq output (format "%s occurs %d times" string number)) Note: message does an implicit "format": (message "%s occurs %d times" string number) |
|
Assignment |
$variable = "stuff"; |
(setq variable "stuff") (set 'variable "stuff") |
|
Assign to a variable indirectly |
our $variable = "what"; our $indirect = "variable"; { no strict "refs"; ${ $indirect } = "hey"; print "well, $variable \n"; } ## prints "well, hey" |
(let* ( (variable "what") (indirect 'variable) ) ; Note *single* quote (set indirect "hey") (message "well, %s" variable)) ;; prints "well, hey" A difference from perl: we can't just use the variable name quoted as a string, in elisp, indirect assignment requires a variable's symbol (hence the use of the single-quote). |
|
Quoting a String |
'quotation' | "quotation" |
|
Interpolated quotes |
"Eat my $madlibs, okay?" |
No real equivalent in elisp (no sigils). This works for environment variables: (setq script-location (substitute-in-file-name "$HOME/bin")) |
| String concatenation | $newstring = "Eat my" . $madlibs . ", okay?"; |
(setq newstring (concat "Eat my" madlibs ", okay?")) |
| Global variables | our $global="initial definition"; |
(defvar global "initial definition" "A global variable for doing stuff globally.") (defcustom user_parameter "default setting" "Change this if you disagree with my default, fool") |
|
Dynamic scoping |
{local $variable1 = "hey"; local $variable2 = "ho"; } |
(let ( (variable1 "hey") (variable2 "ho") )) Or the less surprising: (let* ( (variable1 "hey") (variable2 "ho") (variable3 variable2) )) |
|
Lexical scoping |
{my $lexical_dis = 1; my $lexical_luthor = 2; ... } |
(require 'cl) (lexical-let ((lexical-dis 1) (lexical-luthor 2)) ... ) |
| Error messages |
Undefined subroutine &main:: ... called Global symbol " ... " requires explicit package name bash: ... Permission denied (You forgot to make it "executable".) |
Symbol's definition as function is void: ... Symbol's value as variable is void: ... Wrong type argument: commandp, ... (You forgot the "(interactive)".) |
|
Evaluating code stored in a variable: |
$code = "somefunc( $blah[2] );" eval $code; |
(setq code '(somefunc (car (cdr blah)))) (eval code) Note: Single quote delays evaluation. A more exact parallel, with the code in the form of a string: (setq code-string "(somefunc (car (cdr blah)))") (eval (read code-string) |
| Trapping errors |
use Carp; eval { my $ratio = $a / $b; } if ($@) { carp "Problem with ratio of $a and $b: $@"; } |
(condition-case nil (setq ratio (/ a b)) (error (message "Problem with integer divide of %s by %s" (pp-to-string a) (pp-to-string b)))) |
|
Closures
| A perl closure example | None in elisp |
|
repeat/untill |
$message = "Please input the name: "; do { ### read in the filename $message = "Not valid, try again: "; } until (not (-e $name)) |
(setq message = "Please input the name: ) (setq default-location (file-name-as-directory default-location)) (while (progn (setq filename (expand-file-name (read-file-name message default-location))) (setq message "Not valid, try again: " ) (file-exists-p filename))) |
| Conditionals |
if ( is_first_time ) { print STDERR "This is the FIRST time."; print "we use this string the FIRST time."; } else { print STDERR "This is the SECOND time."; print "we use this string the SECOND time."; } |
(if (first-time-p) (progn ;; needed to glue together multi-line then clause (message "This is the FIRST time.") (insert "we use this string the FIRST time.") (insert "\n")) ;; the else clause has an "implicit progn" (message "This is the SECOND time") (insert "we use this string the SECOND time.") (insert "\n")) |
|
elsif | No elisp equivalent, but see "cond" below... | |
|
case statement |
use Switch 'Perl6'; given ($test_this) { when /something/ { print "case 1" } when (eq "case two string") { print "case 2" } else { print "default" } } |
(cond ((string-match "something" test_this) (message "case 1")) ((string= test_this "case two string") (message "case 2")) (t (message "default"))) |
|
logical operators for short-circuit/
lazy evaluation
|
(DEBUG) and print STDERR "Problem!\n"; close IT or die; |
(and debug_flag (message "Problem!")
(or (...) (...)) |
| For each item in a list, do something |
foreach $item (@item_list) { } |
(require 'cl) (dolist (item item-list) ...) Alternately: (mapc (lambda (item) ... ) item-list) |
| Do something to each item in a list |
@new-list = map { some_func($_) } @item_list; |
(setq new-list (mapcar 'some-func item-list)) |
| Do something to each item in a list (part II) |
my @new_list = map { "Prefix: $_" } ("AAA", "BBB", "CCC"); Result: ('Prefix: AAA', 'Prefix: BBB', 'Prefix: CCC'); |
(setq temp-list (mapcar (lambda (item) (concat "Prefix: " item)) '("AAA" "BBB" "CCC"))) Result: ("Prefix: AAA" "Prefix: BBB" "Prefix: CCC") |
| Splitting a string |
@directory_levels = split m{/}, $filename; | (setq directory-levels-list (split-string filename "[/]" )) |
| Joining strings |
join( "/", @directory-levels) |
(mapconcat 'identity directory-levels "/") ;; Note: identity is the way to do nothing |
|
Regexps: |
(this|that) $pattern = "<\s*(.*?)\s*>"; |
\(this\|that\) (setq pattern "<[ \t]*\\(.*?\\)[ \t]*>") ;; Note \( gets a second slash, but \t does not |
|
String matching:
Perl defaults to
$_ and emacs to the
current buffer |
undef $/; $_ = <>; m{ $pattern }; $first_capture = $1; |
(set-buffer some-stuff) (if (re-search-forward pattern nil t) ;; uses current buffer (setq first-capture (match-string 1))) ;; match-string defaults to match data from current buffer. |
| Matching inside a given string |
if( $some_string =~ m{ $pattern } ) { $first_capture = $1; } |
(string-match pattern some-string) (setq first_capture (match-string 1 some-string)) ;; need to use string name again with match-string |
| Making a global change |
$string =~ s/TAG/current value/g; |
(setq string (replace-regexp-in-string "TAG" "current value" string) Alternately, working in the current buffer: (while (re-search-forward "TAG" nil t) (replace-match "current value" nil nil)) |
| Natural data structures |
arrays and hashes |
lists and alists
(and hashes. and property lists. and...) Note: alists are ordered hashes with slow look-up times. |
| | |