Modulinos: Difference between revisions

From Rosetta Code
Content added Content deleted
(J)
Line 161: Line 161:
=={{header|J}}==
=={{header|J}}==


Probably the simplest way to achive what I imagine "scripted main" to be, in J, involves the use of the [http://www.jsoftware.com/help/dictionary/dx009.htm 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.
Probably the simplest way to achive what I imagine "scripted main" to be, in J, involves the use of the [http://www.jsoftware.com/help/dictionary/dx009.htm 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:
Here is an example "scripted main" program, using this approach:

Revision as of 18:01, 4 March 2011

Modulinos is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

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 have scripted main by default; as long as main() is not included in the header file, this program's (empty) API is accessible by other C code.

<lang c>#include "scriptedmain.h"

  1. include <stdio.h>
  2. include <unistd.h>

int main(int argc, char **argv) { char cwd[1024]; getcwd(cwd, sizeof(cwd));

printf("Directory: %s\n", cwd);

printf("Program: %s\n", argv[0]);

printf("Number of Args: %d\n", argc);

int i; for (i = 0; i < argc; i++) { printf("Arg: %s\n", argv[i]); }

return 0; }</lang>


C++

C++ has scripted main by default.

<lang cpp>#include <iostream>

  1. include <unistd.h>

using namespace std;

int main(int argc, char **argv) { char cwd[1024]; getcwd(cwd, sizeof(cwd));

cout << "Directory: " << cwd << endl;

cout << "Program: " << argv[0] << endl;

cout << "Number of Args: " << argc << endl;

int i; for (i = 0; i < argc; i++) { cout << "Arg: " << argv[i] << endl; }

return 0; }</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.

<lang lisp>#!/bin/bash

  1. |

exec clisp -q -q $0 $0 ${1+"$@"} exit |#

Usage
./scriptedmain.lisp
With help from Rainer Joswig
http://www.math.utexas.edu/pipermail/maxima/2007/006523.html

(defun main (args)

(format t "Directory: ~a~%"
 #+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))
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>

Emacs Lisp

Emacs has scripted main, though older versions require an obscure shebang syntax.

<lang lisp>:;exec emacs -batch -l $0 -f scripted-main $*

Shebang from John Swaby
http://www.emacswiki.org/emacs/EmacsScripts

(defun scripted-main ()

(message "Directory: %s" default-directory)
(message "Program: %s" (nth 2 command-line-args))
(message "Number of Args: %d" (length command-line-args))
(mapcar (lambda (x) (message "Arg: %s" x)) command-line-args))</lang>

Erlang

Erlang has scripted main by default.

<lang erlang>-module(scriptedmain). -import(lists, [map/2]).

main(Args) -> io:format("Directory: ~s~n", [filename:absname("")]), io:format("Program: ~s~n", [?FILE]), io:format("Number of Args: ~w~n", [length(Args)]), map (fun(Arg) -> io:format("Arg: ~s~n", [Arg]) end, Args).</lang>

Haskell

Haskell has scripted main by default.

<lang haskell>#!/usr/bin/env runhaskell

module ScriptedMain where

import System.Directory (getCurrentDirectory) import System (getProgName, getArgs) import Control.Monad (mapM_)

main :: IO () main = do directory <- getCurrentDirectory program <- getProgName args <- getArgs

putStrLn $ "Directory: " ++ directory putStrLn $ "Program: " ++ program putStrLn $ "Number of Args: " ++ (show . length) args mapM_ (\x -> putStrLn $ "Arg: " ++ x) args</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.

<lang java>public class ScriptedMain {

   public static void main(String[] args) {
       System.out.println("Directory: " +
               ScriptedMain.class.getProtectionDomain().getCodeSource().getLocation().getPath());
       System.out.println("Program: " + ScriptedMain.class.getName());
       System.out.println("Number of Args: " + args.length);
       for (int i = 0; i < args.length; i++) {
           System.out.println("Arg: " + args[i]);
       }
   }

}</lang>

Lua

Lua has scripted main by default, using an obscure syntax (an ellipsis of all things).

<lang lua>#!/usr/bin/env lua

os = require("os")

function main(arg) print("Directory: " .. os.execute("pwd"))

print("Program: " .. debug.getinfo(1).source)

print("Number of Args: " .. #arg)

for i,a in ipairs(arg) do print("Arg: " .. a) end

end

if type(package.loaded[(...)]) ~= "userdata" then main(arg) else module(..., package.seeall) end</lang>

newLISP

newLISP lacks scripted main, but the feature is easily added.

<lang lisp>#!/usr/bin/env newlisp

(context 'SCRIPTED-MAIN)

(define (main) (println "Directory: " (real-path))

(println "Program: " (main-args 1))

(println "Number of Args: " (length (main-args)))

(map (lambda (x) (println "Arg: " x)) (main-args))

(exit))

(if (find "scriptedmain" (main-args 1)) (main))

(context MAIN)</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. The scriptedmain() function is just filler.

<lang matlab>#!/usr/bin/env octave -qf

function scriptedmain() endfunction

function main() printf("Directory: %s\n", pwd()); printf("Program: %s\n", program_name()); printf("Number of Args: %d\n", nargin);

args = argv();

for i = 1:nargin printf("Arg: %s\n", args{i}); endfor

endfunction

main();</lang>

Perl

Perl has scripted main.

<lang perl>#!/usr/bin/env perl

use strict; use Cwd qw(getcwd);

sub main { print "Dirctory: " . getcwd . "\n";

print "Program: $0\n";

print "Number of Args: " . ($#ARGV + 1) . "\n";

foreach my $i (0 .. $#ARGV) { print "Arg: $ARGV[$i]\n"; } }

unless(caller) { main; }</lang>

PHP

PHP does not have scripted main, but the feature is easily added with a regular expression.

<lang php><?php function main($args) { echo "Directory: " . getcwd() . "\n";

echo "Program: " . $_SERVER["SCRIPT_NAME"] . "\n";

echo "Number of Args: " . count($args) . "\n";

foreach($args as $arg) { echo "Arg: $arg\n"; } }

if (preg_match("/scriptedmain/", $_SERVER["SCRIPT_NAME"])) { main($argv); } ?></lang>

Python

Python has scripted main.

<lang python>#!/usr/bin/env python

import os, sys

def main(): print "Directory: " + os.getcwd()

print "Program: " + sys.argv[0]

print "Number of Args: %d" % len(sys.argv)

for arg in sys.argv: print "Arg: " + arg

if __name__=="__main__": main()</lang>

R

R does not have scripted main, but the feature is easily added with regular expressions.

<lang R>#!/usr/bin/Rscript

getProgram <- function(args) { sub("--file=", "", args[grep("--file=", args)]) }

main <- function(program, args) { cat("Directory: ", getwd(), "\n")

cat("Program: ", program, "\n")

cat("Number of Args: ", length(args), "\n")

for (arg in args) { cat("Arg: ", arg, "\n") } }

args <- commandArgs(trailingOnly = FALSE) program <- getProgram(args)

if (length(program) > 0 && length(grep("scriptedmain", program)) > 0) { main(program, args) }

q("no")</lang>

Ruby

Ruby has scripted main by default.

<lang ruby>#!/usr/bin/env ruby

def main puts "Directory: #{Dir.pwd}"

puts "Program: #{$0}"

puts "Number of Args: #{ARGV.length}"

ARGV.each { |arg| puts "Arg: #{arg}" } end

if __FILE__ == $0 main end</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.

<lang sh>#!/usr/bin/env sh

main() { echo "Directory: " `pwd`

echo "Program: $0"

echo "Number of Args: $#"

for arg in $*; do echo "Arg: $arg" done }

  1. From Dennis Williamson
  2. http://stackoverflow.com/questions/2683279/#2687092

if $_ == $0 ; then main fi</lang>