optioner

command module
v0.0.0-...-7dbde00 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 31, 2016 License: BSD-3-Clause Imports: 14 Imported by: 0

README

Generate Functional Options

Functional options can be used to create elegant APIs in Go.

This project will install the command optioner which is a tool to generate functional options. The optioner command is intended to be used with go generate.

The idea of functional options was first introduced in this blog post: Self Referential Functions and Design by Rob Pike. More recently, Dave Cheney presented Functional Options for Friendly APIs.

How ot use:

go get github.com/akualab/optioner
go install github.com/akualab/optioner
cd $GOPATH/src/github.com/akualab/optioner/example
go generate
go test

Documentation can be found at http://godoc.org/github.com/akualab/optioner

Documentation

Overview

optioner is a tool to generate functional options. Intended to be used with go generate; see the invocation in example/example.go.

To learn about functional options, see: http://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis http://commandcenter.blogspot.com.au/2014/01/self-referential-functions-and-design.html

This code was adapted from the stringer cmd (golang.org/x/tools/cmd/stringer/).

optioner will generate a file with code of the form:

  // N sets a value for instances of type Example.
  func N(o int) optExample {
	  return func(t *Example) optExample {
		  previous := t.N
		  t.N = o
		  return N(previous)
	  }
  }

The file is created in the package where the code is generated.

optioner will create options for all the fields in the struct except those that include the tag `opt:"-"`.

For example, given this snippet,

  package example

  //go:generate optioner -type Example
  type Example struct {
	  N      int
	  FSlice []float64 `json:"float_slice"`
	  Map    map[string]int
	  Name   string `opt:"-" json:"name"`
	  ff     func(int) int
  }

  func NewExample(name string, options ...optExample) *Example {

	  // Set required values and initialize optional fields with default values.
	  ex := &Example{
		  Name:   name,
		  N:      10,
		  FSlice: make([]float64, 0, 100),
		  Map:    make(map[string]int),
		  ff:     func(n int) int { return n },
	  }

	  // Set options.
	  ex.Option(options...)
  }

go generate will generate option functions for fields N, FSlice, Map, and ff. Your package users can now set options as follows:

myFunc := func(n int) int {return 2 * n}
ex := example.NewExample("test", example.N(22), example.Ff(myFunc))

the new struct "ex" will use default values for "FSlice" and "Map", and custom values for "N" and "ff". Note that the argument "name" in NewExample() is required. For this reason the struct field "name" is excluded using a tag.

To temporarily modify a value, do the following:

prev := ex.Option(N(5)) // previous value is stored in prev.
// do something...
ex.Option(prev) // restores the previous value.

struct fields don't need to be exported, however, the corresponding option will be exported by capitalizing the first letter. Documentation for options is auto-generated in the source file to make it available to package users in godoc format.

It is possible to create options for various types in the same package by using various annotations

//go:generate optioner -type Type1

//go:generate optioner -type Type2

However, to keep function names short, there is no namespaces so you must use different names for different option functions in the same package.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL