diff --git a/basis/help/cookbook/cookbook.factor b/basis/help/cookbook/cookbook.factor index a957cb3e72..65b40543af 100644 --- a/basis/help/cookbook/cookbook.factor +++ b/basis/help/cookbook/cookbook.factor @@ -266,7 +266,7 @@ $nl "To run a script, simply pass it as an argument to the Factor executable:" { $code "./factor cleanup.factor" } "The script may access command line arguments by inspecting the value of the " { $link command-line } " variable. It can also get its own path from the " { $link script } " variable." -$nl +{ $heading "Example: ls" } "Here is an example implementing a simplified version of the Unix " { $snippet "ls" } " command in Factor:" { $code <" USING: command-line namespaces io io.files io.files.listing @@ -282,6 +282,36 @@ command-line get [ } "You can put it in a file named " { $snippet "ls.factor" } ", and then run it, to list the " { $snippet "/usr/bin" } " directory for example:" { $code "./factor ls.factor /usr/bin" } +{ $heading "Example: grep" } +"The following is a more complicated example, implementing something like the Unix " { $snippet "grep" } " command:" +{ $code <" USING: kernel fry io io.files io.encodings.ascii sequences +regexp command-line namespaces ; +IN: grep + +: grep-lines ( pattern -- ) + '[ dup _ matches? [ print ] [ drop ] if ] each-line ; + +: grep-file ( pattern filename -- ) + ascii [ grep-lines ] with-file-reader ; + +: grep-usage ( -- ) + "Usage: factor grep.factor [...]" print ; + +command-line get [ + grep-usage +] [ + unclip swap [ + grep-lines + ] [ + [ grep-file ] with each + ] if-empty +] if-empty"> } +"You can run it like so," +{ $code "./factor grep.factor '.*hello.*' myfile.txt" } +"You'll notice this script takes a while to start. This is because it is loading and compiling the " { $vocab-link "regexp" } " vocabulary every time. To speed up startup, load the vocabulary into your image, and save the image:" +{ $code "USE: regexp" "save" } +"Now, the " { $snippet "grep.factor" } " script will start up much faster. See " { $link "images" } " for details." +{ $heading "Executable scripts" } "It is also possible to make executable scripts. A Factor file can begin with a comment like the following:" { $code "#! /usr/bin/env factor" } "If the text file is made executable, then it can be run, assuming the " { $snippet "factor" } " binary is in your " { $snippet "$PATH" } "." @@ -291,6 +321,7 @@ $nl { } "cli" "cookbook-application" + "images" } ; ARTICLE: "cookbook-philosophy" "Factor philosophy" @@ -344,15 +375,6 @@ ARTICLE: "cookbook-pitfalls" "Pitfalls to avoid" { "If " { $link run-file } " throws a stack depth assertion, it means that the top-level form in the file left behind values on the stack. The stack depth is compared before and after loading a source file, since this type of situation is almost always an error. If you have a legitimate need to load a source file which returns data in some manner, define a word in the source file which produces this data on the stack and call the word after loading the file." } } ; -ARTICLE: "cookbook-images" "Image file cookbook" -"Factor has the ability to save the entire state of the system into an " { $emphasis "image file" } "." -$nl -"You can save a custom image if you find yourself loading the same libraries in every Factor session; some libraries take a little while to compile, so saving an image with those libraries loaded can save you a lot of time." -$nl -"For example, to save an image with the web framework loaded," -{ $code "USE: furnace" "save" } -"See " { $link "images" } " for details." ; - ARTICLE: "cookbook-next" "Next steps" "Once you have read through " { $link "first-program" } " and " { $link "cookbook" } ", the best way to keep learning Factor is to start looking at some simple example programs. Here are a few particularly nice vocabularies which should keep you busy for a little while:" { $list @@ -377,7 +399,6 @@ ARTICLE: "cookbook" "Factor cookbook" { $subsection "cookbook-application" } { $subsection "cookbook-scripts" } { $subsection "cookbook-compiler" } -{ $subsection "cookbook-images" } { $subsection "cookbook-philosophy" } { $subsection "cookbook-pitfalls" } { $subsection "cookbook-next" } ; diff --git a/core/memory/memory-docs.factor b/core/memory/memory-docs.factor index 8f49d882ee..bfe26823be 100644 --- a/core/memory/memory-docs.factor +++ b/core/memory/memory-docs.factor @@ -68,14 +68,19 @@ HELP: count-instances } } ; ARTICLE: "images" "Images" -"The current image can be saved; the image contains a complete dump of all data and code in the current Factor instance:" +"Factor has the ability to save the entire state of the system into an " { $emphasis "image file" } ". The image contains a complete dump of all data and code in the current Factor instance." { $subsection save } { $subsection save-image } { $subsection save-image-and-exit } "To start Factor with a custom image, use the " { $snippet "-i=" { $emphasis "image" } } " command line switch; see " { $link "runtime-cli-args" } "." $nl +"One reason to save a custom image is if you find yourself loading the same libraries in every Factor session; some libraries take a little while to compile, so saving an image with those libraries loaded can save you a lot of time." +$nl +"For example, to save an image with the web framework loaded," +{ $code "USE: furnace" "save" } "New images can be created from scratch:" { $subsection "bootstrap.image" } -{ $see-also "tools.memory" "tools.deploy" } ; +"The " { $link "tools.deploy" } " tool creates stripped-down images containing just enough code to run a single application." +{ $see-also "tools.memory" } ; ABOUT: "images"