Modulinos: Difference between revisions
(Fixed a bunch of snippets) |
|||
Line 5: | Line 5: | ||
=={{header|C}}== |
=={{header|C}}== |
||
C programs cannot do scripted main, because main() is implicitly included by another program, test.c, even |
C programs cannot normally do scripted main, because main() is implicitly included by another program, test.c, even though scriptedmain.h omits any main() prototype. A compiler directive fixes this. |
||
scriptedmain.h |
|||
The following example will not work with another program, test.c, due to duplicate main() functions at compile time. |
|||
<lang c> |
<lang c>int meaning_of_life();</lang> |
||
scriptedmain.c |
|||
#include <stdio.h> |
|||
#include <unistd.h> |
|||
<lang c>#include <stdio.h> |
|||
int main(int argc, char **argv) { |
|||
char cwd[1024]; |
|||
getcwd(cwd, sizeof(cwd)); |
|||
int meaning_of_life() { |
|||
printf("Directory: %s\n", cwd); |
|||
return 42; |
|||
} |
|||
int __attribute__((weak)) main(int argc, char **argv) { |
|||
printf("Program: %s\n", argv[0]); |
|||
printf("Main: The meaning of life is %d\n", meaning_of_life()); |
|||
return 0; |
|||
printf("Number of Args: %d\n", argc); |
|||
}</lang> |
|||
test.c |
|||
int i; |
|||
for (i = 0; i < argc; i++) { |
|||
printf("Arg: %s\n", argv[i]); |
|||
} |
|||
<lang c>#include "scriptedmain.h" |
|||
#include <stdio.h> |
|||
extern int meaning_of_life(); |
|||
int main(int argc, char **argv) { |
|||
printf("Test: The meaning of life is %d\n", meaning_of_life()); |
|||
return 0; |
return 0; |
||
}</lang> |
}</lang> |
||
=={{header|C++}}== |
=={{header|C++}}== |
||
C++ programs cannot do scripted main, because main() is implicitly included by another program, test.c, even |
C++ programs cannot normally do scripted main, because main() is implicitly included by another program, test.c, even though scriptedmain.h omits any main() prototype. A compiler directive fixes this. |
||
scriptedmain.h |
|||
The following example will not work with another program, test.c, due to duplicate main() functions at compile time. |
|||
<lang cpp>int meaning_of_life();</lang> |
|||
scriptedmain.cpp |
|||
<lang cpp>#include <iostream> |
<lang cpp>#include <iostream> |
||
#include <unistd.h> |
|||
using namespace std; |
using namespace std; |
||
int meaning_of_life() { |
|||
int main(int argc, char **argv) { |
|||
return 42; |
|||
char cwd[1024]; |
|||
} |
|||
getcwd(cwd, sizeof(cwd)); |
|||
int __attribute__((weak)) main(int argc, char **argv) { |
|||
cout << "Directory: " << cwd << endl; |
|||
cout << "Main: The meaning of life is " << meaning_of_life() << endl; |
|||
return 0; |
|||
cout << "Program: " << argv[0] << endl; |
|||
}</lang> |
|||
test.cpp |
|||
cout << "Number of Args: " << argc << endl; |
|||
<lang cpp>#include "scriptedmain.h" |
|||
int i; |
|||
#include <iostream> |
|||
for (i = 0; i < argc; i++) { |
|||
cout << "Arg: " << argv[i] << endl; |
|||
using namespace std; |
|||
} |
|||
extern int meaning_of_life(); |
|||
int main(int argc, char **argv) { |
|||
cout << "Test: The meaning of life is " << meaning_of_life() << endl; |
|||
return 0; |
return 0; |
||
Line 62: | Line 77: | ||
=={{header|Chicken Scheme}}== |
=={{header|Chicken Scheme}}== |
||
Chicken Scheme has the {{{ -ss }}} flag for the interpreter, but compiled Chicken Scheme programs do not have scripted main unless the behavior is added manually to the code. |
Chicken Scheme has the {{{ -ss }}} flag for the interpreter, but compiled Chicken Scheme programs do not have scripted main unless the behavior is added manually to the code. |
||
scriptedmain.scm |
|||
<lang scheme>#!/bin/bash |
<lang scheme>#!/bin/bash |
||
Line 71: | Line 88: | ||
(use posix) |
(use posix) |
||
(require-extension srfi-1) ; lists |
(require-extension srfi-1) ; lists |
||
(require-extension srfi-13) ; strings |
|||
(define (main args) |
|||
(display (format "Directory: ~a\n" (current-directory))) |
|||
(display (format "Program: ~a\n" (cdr (program)))) |
|||
(define (meaning-of-life) 42) |
|||
(display (format "Number of Args: ~a\n" (length args))) |
|||
(map (lambda (x) (display (format "Arg: ~a\n" x))) args) |
|||
(define (main args) |
|||
(display (format "Main: The meaning of life is ~a\n" (meaning-of-life))) |
|||
(exit)) |
(exit)) |
||
Line 94: | Line 105: | ||
(if (equal? (car (program)) 'compiled) |
(if (equal? (car (program)) 'compiled) |
||
(main (cdr (argv))))</lang> |
(main (cdr (argv))))</lang> |
||
test.scm |
|||
<lang scheme>#!/bin/bash |
|||
#| |
|||
exec csi -ss $0 ${1+"$@"} |
|||
exit |
|||
|# |
|||
(define (main args) |
|||
(load "scriptedmain.scm") |
|||
(display (format "Test: The meaning of life is ~a\n" (meaning-of-life))) |
|||
(exit))</lang> |
|||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
Line 99: | Line 122: | ||
In CLISP, this code only works for ./scriptedmain.lisp. |
In CLISP, this code only works for ./scriptedmain.lisp. |
||
scriptedmain.lisp |
|||
<lang lisp>#!/bin/bash |
<lang lisp>#!/bin/bash |
||
Line 108: | Line 133: | ||
;;; Usage: ./scriptedmain.lisp |
;;; Usage: ./scriptedmain.lisp |
||
(defun meaning-of-life () 42) |
|||
;;; With help from Rainer Joswig |
|||
;;; http://www.math.utexas.edu/pipermail/maxima/2007/006523.html |
|||
(defun main (args) |
(defun main (args) |
||
(format t " |
(format t "Main: The meaning of life is ~a~%" (meaning-of-life)) |
||
#+clisp (ext:cd) |
|||
#+lucid (working-directory) |
|||
#+allegro (excl:current-directory) |
|||
#+sbcl (progn *default-pathname-defaults*) |
|||
#+(or :cmucl :scl) (ext:default-directory) |
|||
#+lispworks (hcl:get-working-directory) |
|||
) |
|||
(format t "Program: ~a~%" (car args)) |
|||
(format t "Number of Args: ~a~%" (length args)) |
|||
(loop for arg in args do |
|||
(format t "Arg: ~a~%" arg)) |
|||
(quit)) |
(quit)) |
||
Line 146: | Line 156: | ||
:test #'(lambda (x y) (search x y :test #'equalp))) |
:test #'(lambda (x y) (search x y :test #'equalp))) |
||
(main args)))</lang> |
(main args)))</lang> |
||
test.lisp |
|||
<lang lisp>#!/bin/bash |
|||
#| |
|||
exec clisp -q -q $0 $0 ${1+"$@"} |
|||
exit |
|||
|# |
|||
(load "scriptedmain.lisp") |
|||
(format t "Test: The meaning of life is ~a~%" (meaning-of-life))</lang> |
|||
=={{header|Emacs Lisp}}== |
=={{header|Emacs Lisp}}== |
||
Emacs has scripted main, though older versions require an obscure shebang syntax. |
Emacs has scripted main, though older versions require an obscure shebang syntax. |
||
scriptedmain.el |
|||
<lang lisp>:;exec emacs -batch -l $0 -f scripted-main $* |
|||
<lang lisp>:;exec emacs -batch -l $0 -f main $* |
|||
;;; Shebang from John Swaby |
;;; Shebang from John Swaby |
||
;;; http://www.emacswiki.org/emacs/EmacsScripts |
;;; http://www.emacswiki.org/emacs/EmacsScripts |
||
(defun |
(defun meaning-of-life () 42) |
||
(message "Directory: %s" default-directory) |
|||
(defun main () |
|||
(message "Program: %s" (nth 2 command-line-args)) |
|||
(message "Main: The meaning of life is %d" (meaning-of-life)))</lang> |
|||
<lang lisp>:;exec emacs -batch -l $0 -f main $* |
|||
(message "Number of Args: %d" (length command-line-args)) |
|||
(mapcar (lambda (x) (message "Arg: %s" x)) command-line-args))</lang> |
|||
;;; Shebang from John Swaby |
|||
;;; http://www.emacswiki.org/emacs/EmacsScripts |
|||
(defun main () |
|||
(setq load-path (cons default-directory load-path)) |
|||
(load "scriptedmain.el" nil t) |
|||
(message "Test: The meaning of life is %d" (meaning-of-life)))</lang> |
|||
=={{header|Erlang}}== |
=={{header|Erlang}}== |
||
Erlang has scripted main by default. |
Erlang has scripted main by default. scriptedmain.erl must be compiled before test.erl can access its functions. |
||
scriptedmain.erl |
|||
<lang erlang>-module(scriptedmain). |
<lang erlang>-module(scriptedmain). |
||
-export([meaning_of_life/0]). |
|||
-import(lists, [map/2]). |
-import(lists, [map/2]). |
||
meaning_of_life() -> 42. |
|||
main(Args) -> |
|||
io:format("Directory: ~s~n", [filename:absname("")]), |
|||
main(_) -> |
|||
io:format("Program: ~s~n", [?FILE]), |
|||
io:format(" |
io:format("Main: The meaning of life is ~w~n", [meaning_of_life()]).</lang> |
||
map (fun(Arg) -> io:format("Arg: ~s~n", [Arg]) end, Args).</lang> |
|||
test.erl |
|||
<lang erlang>% Compile scriptedmain.erl first. |
|||
-module(test). |
|||
-import(scriptedmain, [meaning_of_life/0]). |
|||
main(_) -> |
|||
io:format("Test: The meaning of life is ~w~n", [meaning_of_life()]).</lang> |
|||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
Haskell has scripted main, but not for compiled scripts. This is because the primary script must be a module Main, creating a name conflict. |
Haskell has scripted main, but not for compiled scripts. This is because the primary script must be a module Main, creating a name conflict. |
||
scriptedmain.sh |
|||
<lang haskell>#!/usr/bin/env runhaskell |
<lang haskell>#!/usr/bin/env runhaskell |
||
-- Haskell has scripted main, but not for compiled scripts. |
|||
-- This is because the primary script must be a module Main, |
|||
-- creating a name conflict. |
|||
module ScriptedMain where |
module ScriptedMain where |
||
meaningOfLife :: Int |
|||
import System.Directory (getCurrentDirectory) |
|||
meaningOfLife = 42 |
|||
import System (getProgName, getArgs) |
|||
import Control.Monad (mapM_) |
|||
main :: IO () |
main :: IO () |
||
main = putStrLn $ "Main: The meaning of life is " ++ show meaningOfLife</lang> |
|||
main = do |
|||
directory <- getCurrentDirectory |
|||
program <- getProgName |
|||
args <- getArgs |
|||
test.hs |
|||
putStrLn $ "Directory: " ++ directory |
|||
putStrLn $ "Program: " ++ program |
|||
<lang haskell>#!/usr/bin/env runhaskell |
|||
putStrLn $ "Number of Args: " ++ (show . length) args |
|||
mapM_ (\x -> putStrLn $ "Arg: " ++ x) args</lang> |
|||
import ScriptedMain hiding (main) |
|||
main :: IO () |
|||
main = putStrLn $ "Test: The meaning of life is " ++ show meaningOfLife</lang> |
|||
=={{header|J}}== |
=={{header|J}}== |
||
Line 224: | Line 272: | ||
=={{header|Java}}== |
=={{header|Java}}== |
||
Java has scripted main by default. |
Java has scripted main by default. |
||
ScriptedMain.java |
|||
<lang java>public class ScriptedMain { |
<lang java>public class ScriptedMain { |
||
public static int meaningOfLife() { |
|||
return 42; |
|||
System.out.println("Directory: " + |
|||
} |
|||
ScriptedMain.class.getProtectionDomain().getCodeSource().getLocation().getPath()); |
|||
public static void main(String[] args) { |
|||
System.out.println("Program: " + ScriptedMain.class.getName()); |
|||
System.out.println("Main: The meaning of life is " + meaningOfLife()); |
|||
} |
|||
}</lang> |
|||
Test.java |
|||
System.out.println("Number of Args: " + args.length); |
|||
<lang java>public class Test { |
|||
for (int i = 0; i < args.length; i++) { |
|||
public static void main(String[] args) { |
|||
System.out.println("Arg: " + args[i]); |
|||
System.out.println("Test: The meaning of life is " + ScriptedMain.meaningOfLife()); |
|||
} |
|||
} |
|||
} |
|||
}</lang> |
}</lang> |
||
Line 293: | Line 346: | ||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
Lua has scripted main by default, using an obscure syntax (an ellipsis of all things). |
Lua has scripted main by default, using an obscure syntax (an ellipsis of all things). |
||
scriptedmain.lua |
|||
<lang lua>#!/usr/bin/env lua |
<lang lua>#!/usr/bin/env lua |
||
function meaningoflife() |
|||
os = require("os") |
|||
return 42 |
|||
end |
|||
function main(arg) |
function main(arg) |
||
print(" |
print("Main: The meaning of life is " .. meaningoflife()) |
||
print("Program: " .. debug.getinfo(1).source) |
|||
print("Number of Args: " .. #arg) |
|||
for i,a in ipairs(arg) do |
|||
print("Arg: " .. a) |
|||
end |
|||
end |
end |
||
Line 316: | Line 364: | ||
module(..., package.seeall) |
module(..., package.seeall) |
||
end</lang> |
end</lang> |
||
test.lua |
|||
<lang lua>#!/usr/bin/env lua |
|||
sm = require("scriptedmain") |
|||
print("Test: The meaning of life is " .. sm.meaningoflife())</lang> |
|||
=={{header|newLISP}}== |
=={{header|newLISP}}== |
||
newLISP lacks scripted main, but the feature is easily added. |
newLISP lacks scripted main, but the feature is easily added. |
||
scriptedmain.lsp |
|||
<lang lisp>#!/usr/bin/env newlisp |
<lang lisp>#!/usr/bin/env newlisp |
||
(context ' |
(context 'SM) |
||
(define (main) |
|||
(println "Directory: " (real-path)) |
|||
(define (SM:meaning-of-life) 42) |
|||
(println "Program: " (main-args 1)) |
|||
(println "Number of Args: " (length (main-args))) |
|||
(map (lambda (x) (println "Arg: " x)) (main-args)) |
|||
(define (main) |
|||
(println (format "Main: The meaning of life is %d" (meaning-of-life))) |
|||
(exit)) |
(exit)) |
||
Line 338: | Line 389: | ||
(context MAIN)</lang> |
(context MAIN)</lang> |
||
test.lsp |
|||
<lang lisp>#!/usr/bin/env newlisp |
|||
(load "scriptedmain.lsp") |
|||
(println (format "Test: The meaning of life is %d" (SM:meaning-of-life))) |
|||
(exit)</lang> |
|||
=={{header|Octave}}/{{header|MATLAB}}== |
=={{header|Octave}}/{{header|MATLAB}}== |
||
Octave and MATLAB have scripted main by default, because only the first function listed in a program are importable by other programs |
Octave and MATLAB have scripted main by default, because only the first function listed in a program are importable by other programs. |
||
meaningoflife.m |
|||
<lang matlab>#!/usr/bin/env octave -qf |
<lang matlab>#!/usr/bin/env octave -qf |
||
function |
function y = meaning_of_life() |
||
y = 42; |
|||
endfunction |
endfunction |
||
function main() |
function main() |
||
printf(" |
printf("Main: The meaning of life is %d\n", meaning_of_life()); |
||
endfunction |
|||
printf("Program: %s\n", program_name()); |
|||
printf("Number of Args: %d\n", nargin); |
|||
main();</lang> |
|||
args = argv(); |
|||
test.m |
|||
for i = 1:nargin |
|||
printf("Arg: %s\n", args{i}); |
|||
endfor |
|||
<lang matlab>#!/usr/bin/env octave -qf |
|||
endfunction |
|||
printf("Test: The meaning of life is %d\n", meaning_of_life());</lang> |
|||
main();</lang> |
|||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
Perl has scripted main. |
Perl has scripted main. |
||
scriptedmain.pm |
|||
<lang perl>#!/usr/bin/env perl |
<lang perl>#!/usr/bin/env perl |
||
use strict; |
use strict; |
||
use Cwd qw(getcwd); |
|||
sub meaning_of_life { |
|||
return 42; |
|||
} |
|||
sub main { |
sub main { |
||
print " |
print "Main: The meaning of life is " . meaning_of_life() . "\n"; |
||
} |
|||
unless(caller) { main; }</lang> |
|||
print "Program: $0\n"; |
|||
test.pl |
|||
print "Number of Args: " . ($#ARGV + 1) . "\n"; |
|||
<lang perl>#!/usr/bin/env perl |
|||
foreach my $i (0 .. $#ARGV) { |
|||
print "Arg: $ARGV[$i]\n"; |
|||
} |
|||
} |
|||
use strict; |
|||
unless(caller) { main; }</lang> |
|||
use ScriptedMain; |
|||
print "Test: The meaning of life is " . meaning_of_life() . "\n";</lang> |
|||
=={{header|PHP}}== |
=={{header|PHP}}== |
||
PHP does not have scripted main, but the feature is easily added with a regular expression. |
PHP does not have scripted main, but the feature is easily added with a regular expression. |
||
scriptedmain.php |
|||
<lang php><?php |
<lang php><?php |
||
function |
function meaning_of_life() { |
||
return 42; |
|||
echo "Directory: " . getcwd() . "\n"; |
|||
} |
|||
echo "Program: " . $_SERVER["SCRIPT_NAME"] . "\n"; |
|||
echo "Number of Args: " . count($args) . "\n"; |
|||
function main($args) { |
|||
echo "Main: The meaning of life is " . meaning_of_life() . "\n"; |
|||
echo "Arg: $arg\n"; |
|||
} |
|||
} |
} |
||
Line 403: | Line 466: | ||
main($argv); |
main($argv); |
||
} |
} |
||
?></lang> |
|||
test.php |
|||
<lang php><?php |
|||
require_once("scriptedmain.php"); |
|||
echo "Test: The meaning of life is " . meaning_of_life() . "\n"; |
|||
?></lang> |
?></lang> |
||
=={{header|Python}}== |
=={{header|Python}}== |
||
Python has scripted main. |
Python has scripted main. |
||
scriptedmain.py |
|||
<lang python>#!/usr/bin/env python |
<lang python>#!/usr/bin/env python |
||
def meaning_of_life(): |
|||
import os, sys |
|||
return 42 |
|||
def main(): |
def main(): |
||
print " |
print "Main: The meaning of life is %s" % meaning_of_life() |
||
if __name__=="__main__": |
|||
print "Program: " + sys.argv[0] |
|||
main()</lang> |
|||
test.py |
|||
print "Number of Args: %d" % len(sys.argv) |
|||
<lang python>#!/usr/bin/env python |
|||
for arg in sys.argv: |
|||
print "Arg: " + arg |
|||
import scriptedmain |
|||
if __name__=="__main__": main()</lang> |
|||
print "Test: The meaning of life is %s" % scriptedmain.meaning_of_life()</lang> |
|||
=={{header|R}}== |
=={{header|R}}== |
||
R does not have scripted main, but the feature is easily added with regular expressions. |
R does not have scripted main, but the feature is easily added with regular expressions. |
||
scriptedmain.R |
|||
<lang R>#!/usr/bin/Rscript |
<lang R>#!/usr/bin/Rscript |
||
meaningOfLife <- function() { |
|||
42 |
|||
sub("--file=", "", args[grep("--file=", args)]) |
|||
} |
} |
||
main <- function(program, args) { |
main <- function(program, args) { |
||
cat(" |
cat("Main: The meaning of life is", meaningOfLife(), "\n") |
||
} |
|||
getProgram <- function(args) { |
|||
cat("Program: ", program, "\n") |
|||
sub("--file=", "", args[grep("--file=", args)]) |
|||
cat("Number of Args: ", length(args), "\n") |
|||
for (arg in args) { |
|||
cat("Arg: ", arg, "\n") |
|||
} |
|||
} |
} |
||
Line 450: | Line 523: | ||
if (length(program) > 0 && length(grep("scriptedmain", program)) > 0) { |
if (length(program) > 0 && length(grep("scriptedmain", program)) > 0) { |
||
main(program, args) |
main(program, args) |
||
q("no") |
|||
} |
|||
}</lang> |
|||
test.R |
|||
<lang R>#!/usr/bin/Rscript |
|||
source("scriptedmain.R") |
|||
cat("Test: The meaning of life is", meaningOfLife(), "\n") |
|||
q("no")</lang> |
q("no")</lang> |
||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
Ruby has scripted main |
Ruby has scripted main. |
||
scriptedmain.rb |
|||
<lang ruby>#!/usr/bin/env ruby |
<lang ruby>#!/usr/bin/env ruby |
||
def |
def meaning_of_life |
||
42 |
|||
puts "Directory: #{Dir.pwd}" |
|||
end |
|||
puts "Program: #{$0}" |
|||
def main |
|||
puts "Number of Args: #{ARGV.length}" |
|||
puts "Main: The meaning of life is #{meaning_of_life}" |
|||
ARGV.each { |arg| puts "Arg: #{arg}" } |
|||
end |
end |
||
Line 472: | Line 554: | ||
main |
main |
||
end</lang> |
end</lang> |
||
test.rb |
|||
<lang ruby>#!/usr/bin/env ruby |
|||
require "scriptedmain" |
|||
puts "Test: The meaning of life is #{meaning_of_life}"</lang> |
|||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
Line 487: | Line 577: | ||
=={{header|UNIX Shell}}== |
=={{header|UNIX Shell}}== |
||
Bash has scripted main. |
Bash has scripted main. |
||
scriptedmain.sh |
|||
<lang sh>#!/usr/bin/env sh |
<lang sh>#!/usr/bin/env sh |
||
meaning_of_life() { |
|||
return 42 |
|||
echo "Directory: " `pwd` |
|||
} |
|||
echo "Program: $0" |
|||
echo "Number of Args: $#" |
|||
main() { |
|||
for arg in $*; do |
|||
meaning_of_life |
|||
echo "Arg: $arg" |
|||
echo "Main: The meaning of life is $?" |
|||
done |
|||
} |
} |
||
if [[ "$BASH_SOURCE" == "$0" ]] |
|||
# From Dennis Williamson |
|||
then |
|||
# http://stackoverflow.com/questions/2683279/#2687092 |
|||
main |
|||
if [[ $_ == $0 ]]; then |
|||
main |
|||
fi</lang> |
fi</lang> |
||
test.sh |
|||
<lang sh>#!/usr/bin/env sh |
|||
source scriptedmain.sh |
|||
meaning_of_life |
|||
echo "Test: The meaning of life is $?"</lang> |
Revision as of 21:48, 6 March 2011
It is useful to be able to execute a main() function only when a program is run directly. This is a central feature in programming scripts; the feature is called scripted main.
Examples from GitHub.
C
C programs cannot normally do scripted main, because main() is implicitly included by another program, test.c, even though scriptedmain.h omits any main() prototype. A compiler directive fixes this.
scriptedmain.h
<lang c>int meaning_of_life();</lang>
scriptedmain.c
<lang c>#include <stdio.h>
int meaning_of_life() { return 42; }
int __attribute__((weak)) main(int argc, char **argv) { printf("Main: The meaning of life is %d\n", meaning_of_life());
return 0; }</lang>
test.c
<lang c>#include "scriptedmain.h"
- include <stdio.h>
extern int meaning_of_life();
int main(int argc, char **argv) { printf("Test: The meaning of life is %d\n", meaning_of_life()); return 0; }</lang>
C++
C++ programs cannot normally do scripted main, because main() is implicitly included by another program, test.c, even though scriptedmain.h omits any main() prototype. A compiler directive fixes this.
scriptedmain.h
<lang cpp>int meaning_of_life();</lang>
scriptedmain.cpp
<lang cpp>#include <iostream>
using namespace std;
int meaning_of_life() { return 42; }
int __attribute__((weak)) main(int argc, char **argv) { cout << "Main: The meaning of life is " << meaning_of_life() << endl;
return 0; }</lang>
test.cpp
<lang cpp>#include "scriptedmain.h"
- include <iostream>
using namespace std;
extern int meaning_of_life();
int main(int argc, char **argv) { cout << "Test: The meaning of life is " << meaning_of_life() << endl;
return 0; }</lang>
Chicken Scheme
Chicken Scheme has the {{{ -ss }}} flag for the interpreter, but compiled Chicken Scheme programs do not have scripted main unless the behavior is added manually to the code.
scriptedmain.scm
<lang scheme>#!/bin/bash
- |
exec csi -ss $0 ${1+"$@"} exit |#
(use posix) (require-extension srfi-1) ; lists
(define (meaning-of-life) 42)
(define (main args) (display (format "Main: The meaning of life is ~a\n" (meaning-of-life))) (exit))
(define (program) (if (string=? (car (argv)) "csi") (let ((s-index (list-index (lambda (x) (string-contains x "-s")) (argv)))) (if (number? s-index) (cons 'interpreted (list-ref (argv) (+ 1 s-index))) (cons 'unknown ""))) (cons 'compiled (car (argv)))))
(if (equal? (car (program)) 'compiled) (main (cdr (argv))))</lang>
test.scm
<lang scheme>#!/bin/bash
- |
exec csi -ss $0 ${1+"$@"} exit |# (define (main args) (load "scriptedmain.scm") (display (format "Test: The meaning of life is ~a\n" (meaning-of-life))) (exit))</lang>
Common Lisp
Common Lisp has few standards for POSIX operation. Shebangs and command line arguments are hacks.
In CLISP, this code only works for ./scriptedmain.lisp.
scriptedmain.lisp
<lang lisp>#!/bin/bash
- |
exec clisp -q -q $0 $0 ${1+"$@"} exit |#
- Usage
- ./scriptedmain.lisp
(defun meaning-of-life () 42)
(defun main (args)
(format t "Main: The meaning of life is ~a~%" (meaning-of-life)) (quit))
- With help from Francois-Rene Rideau
- http://tinyurl.com/cli-args
(let ((args
#+clisp ext:*args* #+sbcl sb-ext:*posix-argv* #+clozure (ccl::command-line-arguments) #+gcl si:*command-args* #+ecl (loop for i from 0 below (si:argc) collect (si:argv i)) #+cmu extensions:*command-line-strings* #+allegro (sys:command-line-arguments) #+lispworks sys:*line-arguments-list* ))
(if (member (pathname-name *load-truename*) args :test #'(lambda (x y) (search x y :test #'equalp))) (main args)))</lang>
test.lisp
<lang lisp>#!/bin/bash
- |
exec clisp -q -q $0 $0 ${1+"$@"} exit |#
(load "scriptedmain.lisp") (format t "Test: The meaning of life is ~a~%" (meaning-of-life))</lang>
Emacs Lisp
Emacs has scripted main, though older versions require an obscure shebang syntax.
scriptedmain.el
<lang lisp>:;exec emacs -batch -l $0 -f main $*
- Shebang from John Swaby
- http://www.emacswiki.org/emacs/EmacsScripts
(defun meaning-of-life () 42)
(defun main ()
(message "Main: The meaning of life is %d" (meaning-of-life)))</lang>
<lang lisp>:;exec emacs -batch -l $0 -f main $*
- Shebang from John Swaby
- http://www.emacswiki.org/emacs/EmacsScripts
(defun main ()
(setq load-path (cons default-directory load-path)) (load "scriptedmain.el" nil t) (message "Test: The meaning of life is %d" (meaning-of-life)))</lang>
Erlang
Erlang has scripted main by default. scriptedmain.erl must be compiled before test.erl can access its functions.
scriptedmain.erl
<lang erlang>-module(scriptedmain). -export([meaning_of_life/0]). -import(lists, [map/2]).
meaning_of_life() -> 42.
main(_) -> io:format("Main: The meaning of life is ~w~n", [meaning_of_life()]).</lang>
test.erl
<lang erlang>% Compile scriptedmain.erl first.
-module(test). -import(scriptedmain, [meaning_of_life/0]).
main(_) -> io:format("Test: The meaning of life is ~w~n", [meaning_of_life()]).</lang>
Haskell
Haskell has scripted main, but not for compiled scripts. This is because the primary script must be a module Main, creating a name conflict.
scriptedmain.sh
<lang haskell>#!/usr/bin/env runhaskell
-- Haskell has scripted main, but not for compiled scripts. -- This is because the primary script must be a module Main, -- creating a name conflict.
module ScriptedMain where
meaningOfLife :: Int meaningOfLife = 42
main :: IO () main = putStrLn $ "Main: The meaning of life is " ++ show meaningOfLife</lang>
test.hs
<lang haskell>#!/usr/bin/env runhaskell
import ScriptedMain hiding (main)
main :: IO () main = putStrLn $ "Test: The meaning of life is " ++ show meaningOfLife</lang>
J
Probably the simplest way to achive what I imagine "scripted main" to be, in J, involves the use of the Immex Phrase. Here, just before the script ends, you define the "main" which would take control if the script was used as a stand alone program.
Here is an example "scripted main" program, using this approach:
<lang j>NB. example "scripted main" code, saved as sm.ijs myName=: 'My name is George' 9!:29]1 9!:27'smoutput myName'</lang>
Here is an example consumer, which is another "scripted main" program:
<lang j>NB. example "alternate main" code require'sm.ijs' 9!:29]1 9!:27'smoutput length: ,":#myName'</lang>
Here is another example consumer. This example is library code, without any main:
<lang j>NB. example "non main" library code require'sm.ijs' 9!:29]0 reversed=:|.myName</lang>
Java
Java has scripted main by default.
ScriptedMain.java
<lang java>public class ScriptedMain { public static int meaningOfLife() { return 42; }
public static void main(String[] args) { System.out.println("Main: The meaning of life is " + meaningOfLife()); } }</lang>
Test.java
<lang java>public class Test { public static void main(String[] args) { System.out.println("Test: The meaning of life is " + ScriptedMain.meaningOfLife()); } }</lang>
LLVM
LLVM has scripted main by default.
<lang llvm>@msg_directory = internal constant [15 x i8] c"Directory: %s\0A\00" @msg_program = internal constant [13 x i8] c"Program: %s\0A\00" @msg_argc = internal constant [20 x i8] c"Number of Args: %d\0A\00" @msg_arg = internal constant [10 x i8] c"Arg = %s\0A\00"
declare i32 @printf(i8* noalias nocapture, ...) declare i8* @getcwd(i8*, i32)
define i32 @main(i32 %argc, i8** %argv) { %cwd = alloca [1024 x i8]
%cwd_ptr = getelementptr inbounds [1024 x i8]* %cwd, i32 0, i32 0
call i8* @getcwd(i8* %cwd_ptr, i32 1024)
call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @msg_directory, i32 0, i32 0), i8* %cwd_ptr)
%program_ptr = getelementptr inbounds i8** %argv, i32 0
%program = load i8** %program_ptr
call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([13 x i8]* @msg_program, i32 0, i32 0), i8* %program)
call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([20 x i8]* @msg_argc, i32 0, i32 0), i32 %argc)
%i = alloca i32 store i32 0, i32* %i br label %for_args
for_args:
%i_val = load i32* %i
%arg_ptr = getelementptr inbounds i8** %argv, i32 %i_val %arg = load i8** %arg_ptr call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @msg_arg, i32 0, i32 0), i8* %arg)
%new_i_val = add i32 %i_val, 1 store i32 %new_i_val, i32* %i
%more_args = icmp slt i32 %new_i_val, %argc br i1 %more_args, label %for_args, label %end_for_args
end_for_args:
ret i32 0 }</lang>
Lua
Lua has scripted main by default, using an obscure syntax (an ellipsis of all things).
scriptedmain.lua
<lang lua>#!/usr/bin/env lua
function meaningoflife() return 42 end
function main(arg) print("Main: The meaning of life is " .. meaningoflife()) end
if type(package.loaded[(...)]) ~= "userdata" then main(arg) else module(..., package.seeall) end</lang>
test.lua
<lang lua>#!/usr/bin/env lua sm = require("scriptedmain") print("Test: The meaning of life is " .. sm.meaningoflife())</lang>
newLISP
newLISP lacks scripted main, but the feature is easily added.
scriptedmain.lsp
<lang lisp>#!/usr/bin/env newlisp
(context 'SM)
(define (SM:meaning-of-life) 42)
(define (main) (println (format "Main: The meaning of life is %d" (meaning-of-life))) (exit))
(if (find "scriptedmain" (main-args 1)) (main))
(context MAIN)</lang>
test.lsp
<lang lisp>#!/usr/bin/env newlisp
(load "scriptedmain.lsp") (println (format "Test: The meaning of life is %d" (SM:meaning-of-life))) (exit)</lang>
Octave/MATLAB
Octave and MATLAB have scripted main by default, because only the first function listed in a program are importable by other programs.
meaningoflife.m
<lang matlab>#!/usr/bin/env octave -qf
function y = meaning_of_life() y = 42; endfunction
function main() printf("Main: The meaning of life is %d\n", meaning_of_life()); endfunction
main();</lang>
test.m
<lang matlab>#!/usr/bin/env octave -qf
printf("Test: The meaning of life is %d\n", meaning_of_life());</lang>
Perl
Perl has scripted main.
scriptedmain.pm
<lang perl>#!/usr/bin/env perl
use strict;
sub meaning_of_life { return 42; }
sub main { print "Main: The meaning of life is " . meaning_of_life() . "\n"; }
unless(caller) { main; }</lang>
test.pl
<lang perl>#!/usr/bin/env perl
use strict; use ScriptedMain;
print "Test: The meaning of life is " . meaning_of_life() . "\n";</lang>
PHP
PHP does not have scripted main, but the feature is easily added with a regular expression.
scriptedmain.php
<lang php><?php function meaning_of_life() { return 42; }
function main($args) { echo "Main: The meaning of life is " . meaning_of_life() . "\n"; }
if (preg_match("/scriptedmain/", $_SERVER["SCRIPT_NAME"])) { main($argv); } ?></lang>
test.php
<lang php><?php require_once("scriptedmain.php"); echo "Test: The meaning of life is " . meaning_of_life() . "\n"; ?></lang>
Python
Python has scripted main.
scriptedmain.py
<lang python>#!/usr/bin/env python
def meaning_of_life(): return 42
def main(): print "Main: The meaning of life is %s" % meaning_of_life()
if __name__=="__main__": main()</lang>
test.py
<lang python>#!/usr/bin/env python
import scriptedmain
print "Test: The meaning of life is %s" % scriptedmain.meaning_of_life()</lang>
R
R does not have scripted main, but the feature is easily added with regular expressions.
scriptedmain.R
<lang R>#!/usr/bin/Rscript
meaningOfLife <- function() { 42 }
main <- function(program, args) { cat("Main: The meaning of life is", meaningOfLife(), "\n") }
getProgram <- function(args) { sub("--file=", "", args[grep("--file=", args)]) }
args <- commandArgs(trailingOnly = FALSE) program <- getProgram(args)
if (length(program) > 0 && length(grep("scriptedmain", program)) > 0) { main(program, args) q("no") }</lang>
test.R
<lang R>#!/usr/bin/Rscript
source("scriptedmain.R")
cat("Test: The meaning of life is", meaningOfLife(), "\n")
q("no")</lang>
Ruby
Ruby has scripted main.
scriptedmain.rb
<lang ruby>#!/usr/bin/env ruby
def meaning_of_life 42 end
def main puts "Main: The meaning of life is #{meaning_of_life}" end
if __FILE__ == $0 main end</lang>
test.rb
<lang ruby>#!/usr/bin/env ruby
require "scriptedmain"
puts "Test: The meaning of life is #{meaning_of_life}"</lang>
Tcl
<lang tcl>proc main {args} {
puts "Directory: [pwd]" puts "Program: $::argv0" puts "Number of args: [llength $args]" foreach arg $args {puts "Arg: $arg"}
}
if {$::argv0 eq [info script]} {
main {*}$::argv
}</lang>
UNIX Shell
Bash has scripted main.
scriptedmain.sh
<lang sh>#!/usr/bin/env sh
meaning_of_life() { return 42 }
main() { meaning_of_life echo "Main: The meaning of life is $?" }
if "$BASH_SOURCE" == "$0" then
main
fi</lang>
test.sh
<lang sh>#!/usr/bin/env sh source scriptedmain.sh meaning_of_life echo "Test: The meaning of life is $?"</lang>