'''[http://www.chiselapp.com/user/pooryorick/repository/ycl/%|%ycl]''', short for '''Y'''orick's '''C'''omputing too'''L'''kit, is [PYK]'s collection of miscellaneous procedures and programs. ** Installation ** To download ycl: ====== fossil clone http://chiselapp.com/user/pooryorick/repository/ycl ycl.fossil ====== Then, open the fossil and add `/path/to/opened/fossil/packages` to [auto_path%|%$auto_path%|%] There is also a helper script, .../ycl/bin/yclrun, which will automatically adjust $auto_path, and can be used as wrapper: ======none tclsh /path/to/opened/fossil/packages/ycl/bin/yclrun myscript.tcl ====== There is another helper script for an interactive shell: ======none tclsh /path/to/opened/fossil/packages/ycl/bin/yclsh ====== [Zipguy] 2013-11-24: How about if you put all those files into a folder structure? Even one folder, named 'ycl', or 'app-ycl' would work good. Then you could either zip them (or you could have gz'ed them), or SDX them (into a starkit) which would make it a lot easier to download them? There are way too many files for me to chase, individually, even though they look quite interesting. Probably a version would be good too, so you could check it, and see if you've already downloaded the latest version. [pyk]: you can get this by logging into the repository as anonymous, and then choosing to download the zip or tarball for the commit you're interested in. ** Usage ** The documentation appears in the source code immediately prior to each function declaration. It is in a text format which is intended to be reasonably intuitive even without much knowledge of Tcl. Most packages have test suites (look for files ending in .test), which provide examples. ** `ycl/bin/ycl` ** The script `ycl/bin/ycl` can be used to call a command in ycl from a shell. *** synopsis *** : `ycl/bin/ycl` `cmd` ''package'' ''command'' ?''args''? ''command'' is a command available in ''package'' *** Example *** From an [sh] shell: ======none $ tclsh /cygdrive/c/Users/yorick/Documents/ycl/src/packages/ycl/bin/ycl cmd 'math rand' randprint_256 BUV9z#=Zu=dAi@y^ytLk1LrTKRp35tbqN^LgqkH7Z6 ====== ** Contents ** *** chan *** '''tplex''': A threaded non-blocking channel multiplexer that has various modes. It can act as a buffer for a single channel, which is the right tool for capturing [stderr] from an `[open]` or `[exec]` pipeline. It can act as a multiplexer sending the contents of the channel to multiple recipeient channels. It can act as a sink to just drain a channel. '''chunked''': A [reflected channel] that wraps another channel, translating its contents from [Hypertext Transfer Protocol%|%HTTP] chunked format. Written as a reflected channel instead of a [transchan%|%channel transform] so that the wrapped channel can persist after the chunked wrapper is closed. This feature is useful for persistent HTTP connections. '''wrap''': A skeleton [reflected channel] that wraps another channel. *** comm *** '''`[ycl comm http]`''': An http client that makes use of [coroutine%|%coroutines] and [reflected channel%|%reflected channels]. *** context *** ====== package require ycl::context namespace import [yclprefix]::context::context proc fly {ns args} { puts "$ns is flying!" } proc nofly {ns args} { puts "$ns can't fly!" } context bird bird method fly bird fly bird derive eagle eagle fly bird derive emu emu method fly nofly emu fly #remove emu's restriction set emumethods [namespace ensemble configure emu -map] set emumethods [dict remove $emumethods fly] namespace ensemble configure emu -map $emumethods emu fly ====== *** [ycl coro relay%|%coro relay] *** `[ycl coro relay%|%coro relay]` is a small but complete system that allows cooperating asynchronous coroutines to make and deliver orders. *** [ycl eav%|%eav] *** '''[ycl eav%|%eav]''': An entity-attribute-value system built on [sqlite], featuring a Tcl-ish interface and query capabilities, and traces for maintaining data constraints and reacting in other ways to record updates. *** [Daerth] *** '''[Daerth]''': creates and manages minions of threaded asynchronous pipelined backpressure-mediated compute stations. *** dir *** ====== package require ycl::dir namespace import [yclprefix]::dir ====== '''duplicates''': find duplicate files '''deduplicate''': remove duplicate files '''iter''': iterate over items in a directory tree. ====== for item in [dir iter /my/dir] { #do stuff } ====== *** exec *** '''invoke''': invoke a child program and asynchronously handle [stdio], [stderr], and exit code. See example at [[`[open]`]. *** iter *** Very similar in spirit to [Generator]. Can be used with [[[for in%|%for ... in%|%]]] ====== package require ycl::iter ====== A set of iterators '''file''': iterate over a file, by line or arbitrary function '''string''': iterate over the characters in a string *** format *** '''sh::shtotcl''': converts the words of a value in sh syntax to a Tcl [list]. *** iter::for *** ====== package require ycl::iter::for ====== '''[for in%|%for ... in]''': a convenient loop construct for working with iterators *** [knit] *** See [knit]. *** list *** ====== variable fruits {apple banana orange pear kiwi} proc is_fruit item { variable fruits return [expr {$item in $fruits}] } ====== The functions, '''all'', '''any''', '''are''', and '''which''' also support an `in $list` pattern. '''all''': true if all items in a list pass the specified test ====== all {banana cookie} [list apply [list x {variable fruits; expr {$x in $fruits}} [namespace current]]] all {banana cookie} in $fruits # -> 0 ====== '''any''': true if any items in a list pass the specified test ====== any {banana cookie} [list apply [list x {variable fruits; expr {$x in $fruits}} [namespace current]]] any {banana cookie} in $fruits # -> 1 ====== '''are''': a list containing true/false answers indicating whether items in a list pass the specified test ====== are {banana cookie} [list apply [list x {variable fruits; expr {$x in $fruits}} [namespace current]]] are {banana cookie} in $fruits # -> {1 0} ====== '''`dedent`''': Remove common whitespace from list items. '''`filter`''' ''list'' ''mask'': Filter items from ''list'' using ''mask'', which is a list of boolean values. '''`pick`''': Extract elements from a list by combinations of index, range, and step. '''`sl`''': See [scripted list]. '''which''': a list of items from a list that pass the specified test ====== which {banana cookie} [list apply [list x {variable fruits; expr {$x in $fruits}} [namespace current]]] which {banana cookie} in $fruits # -> banana ====== *** matrix *** A close-to-drop-in replacement for [tcllib%|%tcllib's] [matrix], but with better performance characteristics since it's more careful about avoiding duplication of data during operation. *** ns *** '''dupcmds''': Copy all commands in a namespace to another namespace, refusing to overwrite any existing commands, and ignoring commands named in in `$args`. In contrast to `[oo::copy] `, if a command is both an alias and a procedure, it is treated as an alias. '''dupensemble''': Copy a [namespace ensemble], and if necessary, the [namespace] that's backing it, along with any child namespaces, recursively. Also replaces in the ensemble map occurrences of the old ensemble name with the new ensemble name. `dupensemble` can be used as the simplese form of [object orientation%|%object system], where each namespace hierarchy is treated as an object. Tcl's [copy-on-write] semantics make this system much more efficient than one would expect at first blush. `dupensemble` is used by `ycl::shelf` '''dupvars''': duplicates all variables in a namespace to another namespace *** proc *** '''[procstep%|%tcl step]''': A drop-in replacement for `[proc]` that provides a pre-evaluation hook and an error handling hook for each command in the script. *** upobj *** Together with proc::methods, proc::upmethods, and var::upmethods, compromises an object system much like '''ycl::context'''. Its method calling style provides for `[uplevel] 1` to be the object's namespace, and `[uplevel] 2` to be the caller of the method. This turned out to be a little clunky, and [ycl shelf] is now preferred to this system. ====== #! /bin/env tclsh package require ycl::ns namespace import ycl::ns::object package require ycl::proc namespace import ycl::proc::*method upmethod die {} {} {} { puts "$_ dies." } object chessman import {name die} chessman $ name unknown namespace eval chessman { upmethod move {} {} {} { puts "$_ doesn't know how to move!" } } object pawn pawn parent chessman namespace eval pawn { upmethod move {} {} {} { puts "$_ is plodding forward" } } object knight knight parent chessman namespace eval knight { upmethod move {} {} {} { puts "$_ gallops forward and to the side" } } object amazon namespace eval amazon { upmethod move {args} {} {} { dict with args {} if {$as ni {knight queen}} { puts "$_ can not move as a $as" } else { puts "$_ is moving as a $as" } } } puts "chessman name is: [chessman $ name]" # -> unknown chessman move # -> ::chessman doesn't know how to move! object pawn1 pawn1 parent pawn pawn1 move # -> ::pawn1 is plodding forward puts "pawn1 name is: [pawn1 $ name]" # -> unknown pawn1 $ name {white a} puts "pawn1 name is now: [pawn1 $ name]" # -> white a object knight1 knight1 parent knight knight1 move # -> ::knight1 gallops forward and to the side object knight3 knight3 parent knight2 knight3 parent amazon knight3 move as queen knight3 move as bishop ====== *** package *** '''vcomp''': like `[package vcompare]`, but accepts just about anything as a version string. *** parse *** '''`tcl commands`''': Split a Tcl [script] into its components. This is `[cmdSplit%|%scriptsplit]` '''`tcl iter`''': Uses `ycl coro relay` to deliver the comands in a script read from a [chan%|%channel]. '''`tcl words`''': Split a Tcl [command] into its components. This is `[cmdSplit]`. '''`tcl wordparts`''': Split a logical word from a Tcl command into its literal, escape-sequence, and substitution components. This is `[cmdSplit%|%wordparts]`. '''`tcl stream`''': Incrementally parse a Tcl script from a channel. *** proc *** ====== package require ycl::dir namespace import [yclprefix]::dir ====== '''checkargs''': functional documentation for procedures. Somewhat like [tepam], with additional aspects of [literate programming]. Examples include [http://chiselapp.com/user/pooryorick/repository/ycl/artifact/93cdea1aac40f022%|%ycl::dir::iter], and [http://chiselapp.com/user/pooryorick/repository/ycl/artifact/90bca3673c69e35d%|%ycl::ns::object] '''[proc alias%|%alias]''': an analogue of [interp alias] that avoids the potential negative performance impact. In contrast to [interp alias], extra arguments can not be tacked on to the alias. *** [Quick-Tk%|%quicktcl] *** *** [ycl shelf%|%shelf] *** See [ycl shelf] *** string *** ====== package require ycl::string ====== '''cmp''': Like the [Unix] [http://pubs.opengroup.org/onlinepubs/9699919799/utilities/cmp.html%|%cmp] command, compares two strings and returns the index at which they differ, or -1 if they are identical. Uses a bisect strategy for performance, and for memory efficiency does not extract substrings. Short-circuits when a difference is found. '''shortmatch''': same as [string match], but return -1 if $string doesn't match, and the index of the last char of the shortest match if it does '''dedent''': remove common newline-whitespace '''delimit''': split (partition) a string into substrings using any combination of string, match, or regular expressions, returning both the substrings and the delimiters. *** struct *** '''[nxs]''': Nested heterogeneous structures. Example: `nxs get $mystruct l {0 3 1} d {name Bob friends} l 5`. To set a nested vale: `nxs set mystruct l {0 3 1} d {name Bob friends} = l end Jane`. Extend the functions to additional types of nested structures by adding keys to `nxs::get`, `nxs::set`, and `nxs::unset`. To specialize the library, use `ycl ns dupensemble` to create a copy of it. *** switch *** '''`[lswitch]`''': Like `[switch]`, but each ''pattern'' is a [list] of patterns to match against the item in ''string'' at the corresponding position. All `switch` options are supported. *** text *** '''`ftclp`''': Formats a string as a printable Tcl string. Non-printable characters are transformed into their most simple [Dodekalogue%|%backslash-escaped] representation, and backslash is also escaped. *** tk_combobox_oakley *** Assimilated from [Bryan Oakley%|%Bryan Okley's] [combobox]. *** visual *** '''`slides`''': A simple [presentation program%|%presentation system] in [Tk]. ---- '''[anonymous] - 2016-08-26 01:25:05''' What is the license on your ycl toolkit? It's not totally clear and there are some GPL'd items hidden in it. [PYK] 2016-08-30: Contributors license their contributions independently. As for my contributions, I'm currently handling license requests on a case-by-case basis. <> Package