Series: What is REST?, A Basic REST API, Paging, Search, Security, Token, OpenID.
We consider some choices of how to provide paging through a list resource in a REST API.
Slides: Paging in a REST API.
Code: poemtube on github.
Series: What is REST?, A Basic REST API, Paging, Search, Security, Token, OpenID.
We consider some choices of how to provide paging through a list resource in a REST API.
Slides: Paging in a REST API.
Code: poemtube on github.
Series: What is REST?, A Basic REST API, Paging, Search, Security, Token, OpenID.
I’ll walk you through the code of a simple REST API I am writing to be a kind of YouTube for poetry.
Slides: A Basic REST API.
Code: poemtube on github.
Series: What is REST?, A Basic REST API, Paging, Search, Security, Token, OpenID.
The basic concepts of REST APIs:
Slides: What is REST?.
Code: poemtube on github.
Bash arrays are a lot like Bash Associative Arrays, but with numbers as keys.
Here’s a quick reference.
$ declare -a MYARR # Create an array $ MYARR[3]=foo # Put a value into an array $ echo ${MYARR[3]} # Get a value out of an array foo $ echo MYARR[3] # WRONG MYARR[0] $ echo $MYARR[3]] # WRONG [3]
$ declare -a MYARR # Explicitly declare $ MYARR[3]=foo # Or this line implicitly makes it an array $ MYARR[4]=bar # Can add values one by one
$ declare -a MYARR=(a b c) # Initialise all at once $ echo ${MYARR[0]} a $ echo ${MYARR[1]} b $ echo ${MYARR[2]} c
$ declare -a MYARR # Or declare separately $ MYARR=(a b c) # Then initialise $ echo ${MYARR[0]} a $ echo ${MYARR[1]} b $ echo ${MYARR[2]} c
$ declare -a MYARR=(a b c) $ MYARR=("${MYARR[@]}" d) # Add an element $ echo ${MYARR[@]} a b c d $ declare -a MYARR2=(e f g) $ MYARR=("${MYARR[@]}" "${MYARR2[@]}") # Concatenate arrays $ echo ${MYARR[@]} a b c d e f g
$ declare -a MYARR $ MYARR[3]=foo $ echo ${MYARR[0]} # Unassigned values are empty $ echo ${MYARR[4]} # Unassigned values are empty $ MYARR[seven]=bar # A text index is treated as 0 $ echo ${MYARR[0]} bar $ echo ${MYARR[seven]} # A text index is treated as 0 bar
$ K=3 $ MYARR[$K]=baz # Variables containing numbers work like numbers $ echo ${MYARR[$K]} baz $ echo ${MYARR[3]} # Obviously the value is accessible via the actual index baz $ K=foo $ MYARR[$K]=bash # Variables containing text are treated as 0 $ echo ${MYARR[0]} bash
$ declare -a MYARR=(a b c) $ echo ${#MYARR[@]} # Length of an array 3 $ echo $#MYARR[@] # WRONG 0MYARR[@] $ echo ${#MYARR} # WRONG 1
$ MYARR[7]=x $ echo ${#MYARR[@]} # Only existing indices count in the length 4
$ declare -a MYARR=(a bb ccc) $ echo ${#MYARR[0]} # Length of an individual element 1 $ echo ${#MYARR[1]} 2 $ echo ${#MYARR[2]} 3
$ declare -a MYARR=("a 1" b c)
$ # Loop through array values
$ for V in "${MYARR[@]}"; do echo $V; done
a 1
b
c
$ for V in ${MYARR[@]}; do echo $V; done #WRONG
a
1
b
c
$ echo "${!MYARR[@]}" # Print all indices - quoted, but quotes removed by echo 0 1 2 $ echo "${MYARR[@]}" # Print all values - quoted, but quotes removed by echo a 1 b c
$ declare -a MYARR $ MYARR[3]=x $ echo ${MYARR[3]} x $ unset MYARR $ declare -a MYARR $ echo ${MYARR[3]}
$ MYARR[2]=foo
$ echo ${MYARR[2]}
foo
$ unset ${MYARR[2]} # WRONG
$ echo ${MYARR[2]}
foo
$ unset MYARR[2] # To delete from an array, use "unset" with similar syntax to assigning
$ echo ${MYARR[2]}
$ MYARR[3]=quux
$ echo ${MYARR[3]}
quux
$ K=3
$ unset MYARR[$K] # Can unset using a variable for the key too
$ echo ${MYARR[3]}
$ declare -a MYARR=(a b c d e f) $ MYARR=("${MYARR[@]:0:3}" "${MYARR[@]:4}") # Remove element 3, leaving no gap $ echo ${MYARR[@]}
$ declare -a MYARR=(a b c d e f g) $ echo ${MYARR[@]:2:3} # Extract a sub-array c d e
$ declare -a MYARR=(a b c d e f g) $ echo ${MYARR[@]/d/FOO} # Replace elements that match a b c FOO e f g
$ unset MYARR $ function createmap() { MYARR[5]=bar; } # Implicit creation puts it in the global scope $ echo ${MYARR[5]} $ createmap $ echo ${MYARR[5]} bar
$ unset MYARR $ function createmaplocal() { declare -a MYARR; MYARR[3]=bar; } # Explicit creation puts it in the local scope $ echo ${MYARR[3]} $ createmaplocal $ echo ${MYARR[3]}
In a previous post I outlined how to use if:set and unless:set to execute tasks conditionally in Ant 1.9.1.
Unfortunately, this does not work with macrodefs. When I try to execute a macrodef conditionally like this:
<project xmlns:if="ant:if" xmlns:unless="ant:unless" default="build" > <macrodef name="mymacro"> <sequential> <echo message="inside mymacro"/> </sequential> </macrodef> <target name="build"> <mymacro if:set="doit"/> </target> </project>
When I set the “doit” property and run like this, it fails:
$ ant -Ddoit=true Buildfile: build.xml build: BUILD FAILED build.xml:14: Unknown attribute [ant:if:if:set] Total time: 0 seconds
It looks to me like this is a bug: the if:set attribute is getting passed into the macro, which is complaining that it doesn’t expect an attribute with that name. (If you try to create an attribute with that name, you’ll find that “if:set” is an illegal name…)
However, there is a workaround. You can wrap the call to your macrodef in a <sequential> tag:
<project xmlns:if="ant:if" xmlns:unless="ant:unless" default="build" > <macrodef name="mymacro"> <sequential> <echo message="inside mymacro"/> </sequential> </macrodef> <target name="build"> <sequential if:set="doit"> <mymacro/> </sequential> </target> </project>
And now it works!
$ ant -Ddoit=true Buildfile: build.xml build: [echo] inside mymacro BUILD SUCCESSFUL Total time: 0 seconds
$ ant Buildfile: build.xml build: BUILD SUCCESSFUL Total time: 0 seconds
Conditional execution even when calling a macrodef. Enjoy.