Spec in plsql package - why its required - oracle

Can someone tell me, why we package Spec is required in oracle PL/SQL.
anyway the package body has all the information as spec.

The separation of package Specification from the package Body is a fundamentally important part of the design of languages such as PL/SQL. It's the way that PL/SQL allows you to use the principle of Encapsulation.
The Specification is the way you specify the Public portion of the package, that is, the functions, procedures, types and constants that should be accessible by other program units or external callers.
The Body not only encapsulates the implementation details, but also allows you to create functions and procedures that are Private; that is, they are only allowed to be used by other functions and procedures in the same package, and cannot be called by external callers.
Encapsulation brings a number of benefits - including self-documentation: if a method is Private, you are guaranteed that there will be no calls to it except within the same package - so you are free to change it, secure in the knowledge that your change will at least not break any other system that uses the package.
Packages are useful as APIs; the specification then becomes the documentation of which functions and procedures are designed and intended to be called by other code in the system.

The package specification contains the definition or specification of all the publicly available elements in the package that may be referenced outside of the package.
The specification is like one big declaration section; it does not contain any PL/SQL blocks or executable code. If a specification is well designed, a developer can learn from it everything necessary to use the package. There should never be any need to go “behind” the interface of the specification and look at the implementation,which is in the body.
The distinction drawn between public and private elements in a package gives PL/SQL developers unprecedented control over their data structures and programs. As Booch diagram below displays
Notice the two labels Inside and Outside. Outside consists of all the programs you write that are not a part of the package at hand (the external programs). Inside consists of the package body (the internals or implementation of the
package).
Here are the conclusions we can draw from the Booch diagram:
External programs cannot cross the boundary from outside to inside. That is, an external program may not reference or call any elements defined inside the package body. They are private and invisible outside of the package.
Those elements defined in the package specification (labeled Public in the figure) straddle the boundary between inside and outside. These programs can be called by an external program (from the outside), can be called or referenced by a private program, and can, in turn, call or reference any other element in the package.
Public elements of the package therefore offer the only path to the inside of the package. In this way, the package specification acts as a control mechanism for the package as a whole.
If you find that a formerly private object (such as a module or a cursor) should instead be made public, simply add that object to the package specification and recompile. It will then be visible outside of the package.
This explanation is inspired by oracle pl/sql programming 5th edition by Steven Feuerstein

Related

How to wrap a Go package with only a few modifications?

How can I write a Go package that wraps a library such that calls to overridden functions use my implementation, and non-overridden functions "fall through" to the library I am wrapping?
In particular: I want my Go package to wrap net/http, except I initially want to only replace http.FileServer and http.NotFoundHandler, and leave all other functions the same. My library is a drop-in replacement for existing code that calls other net/http functions I won't overwrite. For example, I want to be able to do:
package main
import (
"log"
http "github.com/jstrieb/my-special-http-lib"
)
func main() {
http.ListenAndServe( // Use the net/http ListenAndServe by "falling through" my library
":8080",
http.FileServer(http.Dir("/usr/share/doc")) // Use my custom, overridden http.FileServer
)
}
What I have tried
I could manually override each function exported by the wrapped library (like below), but I would rather avoid this if possible. This approach is undesirable because it doesn't account for instances where functions I override are called from within the library I am wrapping.
func ExportedFunction(input1 type1) type2 {
return http.ExportedFunction(input1)
}
I could also fully fork the net/http source and change it directly, but I want it to be clear what changes I am making without having to compare against the original version. It also doesn't makes sense to maintain a fork of part of the standard library to only override a few functions.
Justification
I am not looking for commentary on whether this is a "good" idea. I just want to know how to do it.
The plan for this library is to simply change the appearance of the 404 page and the directory listing index page. This purely aesthetic change does not affect the underlying functionality or API of net/http. If it was not structured to wrap all of net/http, then a user would have to switch between using two packages to do the same thing. Then my library could not be considered a "drop-in replacement" for code that already uses net/http.
I also intend to override more functions over time, but the API of my library will always match that of net/http. Doing it this way reduces the need to manually replace calls like http.Function with mylibrary.Function every time the library changes. Moreover, I want to be able to import my replacement in code (using net/http) that I did not write, and don't want to manually refactor.
What you are trying to achieve here is extend the functionality of package. Simple answer here is you cannot do so as of now. Best possible way to achieve this is just doing this manually.
Personally I don't see any harm in having two packages seperate. I this it is more maintainable. Just wrap the functions you want to update. Sometimes all you need is a function.
Not a Go expert, but speaking anecdotally, this would introduce a significant vulnerability if by specifying one dependency you were then able to side-load a different version of it instead with whatever modifications you wanted.
It might speak to the notion of, if this dependency is something you can bring into your application, then you should build a library which builds off the one you want to modify, and import that one in instead. That is to say, given your application A and library B, with your modified library B', you would want to write your application such that A depends on B' which depends on B, which would make the relationship apparent. If you wanted to somehow have A depend on B but be able to side-load B' in dynamically, then that would represent the vulnerability that I allude to earlier.

Registering packages in Go without cyclic dependency

I have a central package that provides several interfaces that other packages are dependent on (let us call one Client). Those other packages, provide several implementations of those first interfaces (UDPClient, TCPClient). I instantiate a Client by calling NewClient in the central package, and it selects and invokes the appropriate client implementation from one of the dependent packages.
This falls apart when I want to tell the central package about those other packages, so it knows what clients it can create. Those dependent client implementations also import the central package, creating a cyclic dependency which Go does not allow.
What's the best way forward? I'd prefer not to mash all those implementations in a single package, and creating a separate registry package seems overkill. Currently I have each implementation register itself with the central package, but this requires that the user knows to import every implementation in every separate binary that makes use of client.
import (
_ udpclient
_ tcpclient
client
)
The standard library solves this problem in multiple ways:
1) Without a "Central" Registry
Example of this is the different hash algorithms. The crypto package just defines the Hash interface (the type and its methods). Concrete implementations are in different packages (actually subfolders but doesn't need to be) for example crypto/md5 and crypto/sha256.
When you need a "hasher", you explicitly state which one you want and instantiate that one, e.g.
h1 := md5.New()
h2 := sha256.New()
This is the simplest solution and it also gives you good separation: the hash package does not have to know or worry about implementations.
This is the preferred solution if you know or you can decide which implementation you want prior.
2) With a "Central" Registry
This is basically your proposed solution. Implementations have to register themselves in some way (usually in a package init() function).
An example of this is the image package. The package defines the Image interface and several of its implementations. Different image formats are defined in different packages such as image/gif, image/jpeg and image/png.
The image package has a Decode() function which decodes and returns an Image from the specified io.Reader. Often it is unknown what type of image comes from the reader and so you can't use the decoder algorithm of a specific image format.
In this case if we want the image decoding mechanism to be extensible, a registration is unavoidable. The cleanest to do this is in package init() functions which is triggered by specifying the blank identifier for the package name when importing.
Note that this solution also gives you the possibility to use a specific implementation to decode an image, the concrete implementations also provide the Decode() function, for example png.Decode().
So the best way?
Depends on what your requirements are. If you know or you can decide which implementation you need, go with #1. If you can't decide or you don't know and you need extensibility, go with #2.
...Or go with #3 presented below.
3) Proposing a 3rd Solution: "Custom" Registry
You can still have the convenience of the "central" registry with interface and implementations separated with the expense of "auto-extensibility".
The idea is that you have the interface in package pi. You have implementations in package pa, pb etc.
And you create a package pf which will have the "factory" methods you want, e.g. pf.NewClient(). The pf package can refer to packages pa, pb, pi without creating a circular dependency.
Those dependent client implementations also import the central package
They should rely on another package defining interfaces that they need to rely on (and that are implemented by the first central package).
This is usually how an import cycle is broken (and/or using dependency inversion).
You have more options described in "Cyclic dependencies and interfaces in Golang".
go list -f can also help visualizing those import cycles.

Public, Private - Upper Case, Lower Case:

New to GoLang, coming from Delphi, C++ :
First time I tried to create my own package in Go, I followed all the instructions about how to lay out the workspace, etc, but I kept on getting a compiler error:
./myPackage.go:52: undefined: myFunc
After poking around a bit I discovered that the public access modifier in Go is achieved simply by declaring a function in upper case. Great.
But when I started experimenting with the container classes - List for starters, I discovered I had to declare a List reference return value like this:
func GetFactors(value *int64) *list.List {...
*list is in lower case.
Same when I declared a local reference to a list - I had to use:
l := list.New()
Again, lower case for list.
So, I'm confused. What is the rule? The list calls and references are obviously public, or I wouldn't be able to call/use them - so why are they in lower case?
In this case, list is the name of the package, which you are importing via import "container/list", and its public members are upper case, like List.
The rule is that public functions, types, etc., should be upper case.
You can alias imported packages however you want, but by default it is just the name of the last part of the package path--in this case, list.
Update: It's not the last part of the package path. It's the actual package name (which is often the same thing).
Note: starting Go 1.5 (Q2/Q3 2015), you will get "protected" import as well (named "internal")!
See Go 1.4 doc:
Go's package system makes it easy to structure programs into components with clean boundaries, but there are only two forms of access: local (unexported) and global (exported).
Sometimes one wishes to have components that are not exported, for instance to avoid acquiring clients of interfaces to code that is part of a public repository but not intended for use outside the program to which it belongs.
The Go language does not have the power to enforce this distinction, but as of Go 1.4 the go command introduces a mechanism to define "internal" packages that may not be imported by packages outside the source subtree in which they reside.
To create such a package, place it in a directory named internal or in a subdirectory of a directory named internal.
When the go command sees an import of a package with internal in its path, it verifies that the package doing the import is within the tree rooted at the parent of the internal directory.
For example, a package .../a/b/c/internal/d/e/f can be imported only by code in the directory tree rooted at .../a/b/c.
It cannot be imported by code in .../a/b/g or in any other repository.
For Go 1.4, the internal package mechanism is enforced for the main Go repository;
from 1.5 and onward it will be enforced for any repository.
Note: the Go Spec for package name don't mention that a package name is always in lowercase.
It only state that its name is represented by an identifier, which is composed of a collection of "letter".
This thread does clarify:
Package names can be anything, you can start them with an uppercase letter if you want to.
But the convention is all lowercase, which I guess saves you the hassle of typing an uppercase letter.
The uppercase/lowercase exportability isn't really relevant to packages since you can't have a private package.
Once you know that, it is easier to recognize:
list.New() for a constructor (always at the package level, to build an initialized instance of a type), like os.NewFile(),
list.List for a struct type of the package list (the other struct type of that same package being list.Element).

Cyclic dependencies and interfaces

I am a long time python developer. I was trying out Go, converting an existing python app to Go. It is modular and works really well for me.
Upon creating the same structure in Go, I seem to land in cyclic import errors, a lot more than I want to. Never had any import problems in python. I never even had to use import aliases. So I may have had some cyclic imports which were not evident in python. I actually find that strange.
Anyways, I am lost, trying to fix these in Go. I have read that interfaces can be used to avoid cyclic dependencies. But I don't understand how. I didn't find any examples on this either. Can somebody help me on this?
The current python application structure is as follows:
/main.py
/settings/routes.py contains main routes depends on app1/routes.py, app2/routes.py etc
/settings/database.py function like connect() which opens db session
/settings/constants.py general constants
/apps/app1/views.py url handler functions
/apps/app1/models.py app specific database functions depends on settings/database.py
/apps/app1/routes.py app specific routes
/apps/app2/views.py url handler functions
/apps/app2/models.py app specific database functions depends on settings/database.py
/apps/app2/routes.py app specific routes
settings/database.py has generic functions like connect() which opens a db session. So an app in the apps package calls database.connect() and a db session is opened.
The same is the case with settings/routes.py it has functions that allow apps to add their sub-routes to the main route object.
The settings package is more about functions than data/constants. This contains code that is used by apps in the apps package, that would otherwise have to be duplicated in all the apps. So if I need to change the router class, for instance, I just have to change settings/router.py and the apps will continue to work with no modifications.
There're two high-level pieces to this: figuring out which code goes in which package, and tweaking your APIs to reduce the need for packages to take on as many dependencies.
On designing APIs that avoid the need for some imports:
Write config functions for hooking packages up to each other at run time rather than compile time. Instead of routes importing all the packages that define routes, it can export routes.Register, which main (or code in each app) can call. In general, configuration info probably flows through main or a dedicated package; scattering it around too much can make it hard to manage.
Pass around basic types and interface values. If you're depending on a package for just a type name, maybe you can avoid that. Maybe some code handling a []Page can get instead use a []string of filenames or a []int of IDs or some more general interface (sql.Rows) instead.
Consider having 'schema' packages with just pure data types and interfaces, so User is separate from code that might load users from the database. It doesn't have to depend on much (maybe on anything), so you can include it from anywhere. Ben Johnson gave a lightning talk at GopherCon 2016 suggesting that and organizing packages by dependencies.
On organizing code into packages:
As a rule, split a package up when each piece could be useful on its own. If two pieces of functionality are really intimately related, you don't have to split them into packages at all; you can organize with multiple files or types instead. Big packages can be OK; Go's net/http is one, for instance.
Break up grab-bag packages (utils, tools) by topic or dependency. Otherwise you can end up importing a huge utils package (and taking on all its dependencies) for one or two pieces of functionality (that wouldn't have so many dependencies if separated out).
Consider pushing reusable code 'down' into lower-level packages untangled from your particular use case. If you have a package page containing both logic for your content management system and all-purpose HTML-manipulation code, consider moving the HTML stuff "down" to a package html so you can use it without importing unrelated content management stuff.
Here, I'd rearrange things so the router doesn't need to include the routes: instead, each app package calls a router.Register() method. This is what the Gorilla web toolkit's mux package does. Your routes, database, and constants packages sound like low-level pieces that should be imported by your app code and not import it.
Generally, try to build your app in layers. Your higher-layer, use-case-specific app code should import lower-layer, more fundamental tools, and never the other way around. Here are some more thoughts:
Packages are good for separating independently usable bits of functionality from the caller's perspective. For your internal code organization, you can easily shuffle code between source files in the package. The initial namespace for symbols you define in x/foo.go or x/bar.go is just package x, and it's not that hard to split/join files as needed, especially with the help of a utility like goimports.
The standard library's net/http is about 7k lines (counting comments/blanks but not tests). Internally, it's split into many smaller files and types. But it's one package, I think 'cause there was no reason users would want, say, just cookie handling on its own. On the other hand, net and net/url are separate because they have uses outside HTTP.
It's great if you can push "down" utilities into libraries that are independent and feel like their own polished products, or cleanly layer your application itself (e.g., UI sits atop an API sits atop some core libraries and data models). Likewise "horizontal" separation may help you hold the app in your head (e.g., the UI layer breaks up into user account management, the application core, and administrative tools, or something finer-grained than that). But, the core point is, you're free to split or not as works for you.
Set up APIs to configure behavior at run-time so you don't have to import it at compile time. So, for example, your URL router can expose a Register method instead of importing appA, appB, etc. and reading a var Routes from each. You could make a myapp/routes package that imports router and all your views and calls router.Register. The fundamental idea is that the router is all-purpose code that needn't import your application's views.
Some ways to put together config APIs:
Pass app behavior via interfaces or funcs: http can be passed custom implementations of Handler (of course) but also CookieJar or File. text/template and html/template can accept functions to be accessible from templates (in a FuncMap).
Export shortcut functions from your package if appropriate: In http, callers can either make and separately configure some http.Server objects, or call http.ListenAndServe(...) that uses a global Server. That gives you a nice design--everything's in an object and callers can create multiple Servers in a process and such--but it also offers a lazy way to configure in the simple single-server case.
If you have to, just duct-tape it: You don't have to limit yourself to super-elegant config systems if you can't fit one to your app: maybe for some stuff a package "myapp/conf" with a global var Conf map[string]interface{} is useful.
But be aware of downsides to global conf. If you want to write reusable libraries, they can't import myapp/conf; they need to accept all the info they need in constructors, etc. Globals also risk hard-wiring in an assumption something will always have a single value app-wide when it eventually won't; maybe today you have a single database config or HTTP server config or such, but someday you don't.
Some more specific ways to move code or change definitions to reduce dependency issues:
Separate fundamental tasks from app-dependent ones. One app I work on in another language has a "utils" module mixing general tasks (e.g., formatting datetimes or working with HTML) with app-specific stuff (that depends on the user schema, etc.). But the users package imports the utils, creating a cycle. If I were porting to Go, I'd move the user-dependent utils "up" out of the utils module, maybe to live with the user code or even above it.
Consider breaking up grab-bag packages. Slightly enlarging on the last point: if two pieces of functionality are independent (that is, things still work if you move some code to another package) and unrelated from the user's perspective, they're candidates to be separated into two packages. Sometimes the bundling is harmless, but other times it leads to extra dependencies, or a less generic package name would just make clearer code. So my utils above might be broken up by topic or dependency (e.g., strutil, dbutil, etc.). If you wind up with lots of packages this way, we've got goimports to help manage them.
Replace import-requiring object types in APIs with basic types and interfaces. Say two entities in your app have a many-to-many relationship like Users and Groups. If they live in different packages (a big 'if'), you can't have both u.Groups() returning a []group.Group and g.Users() returning []user.User because that requires the packages to import each other.
However, you could change one or both of those return, say, a []uint of IDs or a sql.Rows or some other interface you can get to without importing a specific object type. Depending on your use case, types like User and Group might be so intimately related that it's better just to put them in one package, but if you decide they should be distinct, this is a way.
Thanks for the detailed question and followup.
Possible partial, but ugly answer:
Have struggled with the import cyclic dependency problem for a year. For a while, was able to decouple enough so that there wasn't an import cycle. My application uses plugins heavily. At the same time, it uses encode/decode libraries (json and gob). For these, I have custom marshall and unmarshall methods, and equivalent for json.
For these to work, the full type name including the package name must be identical on data structures that are passed to the codecs. The creation of the codecs must be in a package. This package is called from both other packages as well as from plugins.
Everything works as long as the codec package doesn't need to call out to any package calling it, or use the methods or interfaces to the methods. In order to be able to use the types from the package in the plugins, the plugins have to be compiled with the package. Since I don't want to have to include the main program in the builds for the plugins, which would break the point of the plugins, only the codec package is included in both the plugins and the main program. Everything works up until I need to call from the codec package in to the main program, after the main program has called in to the codec package. This will cause an import cycle. To get rid of this, I can put the codec in the main program instead of its own package. But, because the specific datatypes being used in the marshalling/unmarshalling methods must be the same in the main program and the plugins, I would need to compile with the main program package for each of the plugins. Further, because I need to the main program to call out to the plugins I need the interface types for the plugins in the main program. Having never found a way to get this to work, I did think of a possible solution:
First, separate the codec in to a plugin, instead of just a package
Then, load it as the first plugin from the main program.
Create a registration function to exchange interfaces with underlying methods.
All encoders and decoders are created by calls in to this plugin.
The plugin calls back to the main program through the registered interface.
The main program and all the plugins use the same interface type package for this.
However, the datatypes for the actual encoded data are referenced in the main program
with a different name, but same underlying type than in the plugins, otherwise the same import cycle exists. to do this part requires doing an unsafe cast. Wrote
a little function that does a forced cast so that the syntax is clean:
(<cast pointer type*>Cast(<pointer to structure, or interface to pointer to structure>).
The only other issue for the codecs is to make sure that when the data is sent to the encoder, it is cast so that the marshall/unmarshall methods recognize the datatype names. To make that easier, can import both the main program types from one package, and the plugin types from another package since they don't reference each other.
Very complex workaround, but don't see how else to make this work.
Have not tried this yet. May still end up with an import cycle when everything is done.
[more on this]
To avoid the import cycle problem, I use an unsafe type approach using pointers. First, here is a package with a little function Cast() to do the unsafe typecasting, to make the code easier to read:
package ForcedCast
import (
"unsafe"
"reflect"
)
// cast function to do casts with to hide the ugly syntax
// used as the following:
// <var> = (cast type)(cast(input var))
func Cast(i interface{})(unsafe.Pointer) {
return (unsafe.Pointer(reflect.ValueOf(i).Pointer()))
}
Next I use the "interface{}" as the equivalent of a void pointer:
package firstpackage
type realstruct struct {
...
}
var Data realstruct
// setup a function to call in to a loaded plugin
var calledfuncptr func(interface)
func callingfunc() {
pluginpath := path.Join(<pathname>, "calledfuncplugin")
plug, err := plugin.Open(pluginpath)
rFunc, err := plug.Lookup("calledfunc")
calledfuncptr = rFunc.(interface{})
calledfuncptr (&Data)
}
//in a plugin
//plugins don't use packages for the main code, are build with -buildmode=plugin
package main
// identical definition of structure
type realstruct struct {
...
}
var localdataptr *realstruct
func calledfunc(needcast interface{}) {
localdataptr = (*realstruct)(Cast(needcast))
}
For cross type dependencies to any other packages, use the "interface{}" as a void pointer and cast appropriately as needed.
This only works if the underlying type that is pointed to by the interface{} is identical wherever it is cast. To make this easier, I put the types in a separate file. In the calling package, they start with the package name. I then make a copy of the type file, change the package to "package main", and put it in the plugin directory so that the types are built, but not the package name.
There is probably a way to do this for the actual data values, not just pointers, but I haven't gotten that to work right.
One of the things I have done is to cast to an interface instead of a datatype pointer. This allows you to send interfaces to packages using the plugin approach, where there is an import cycle. The interface has a pointer to the datatype, and then you can use it for calling the methods on the datatype from the caller from the package that called in to the plugin.
The reason why this works is that the datatypes are not visible outside of the plugin. That is, if I load to plugins, which are both package main, and the types are defined in the package main for both, but are different types with the same names, the types do not conflict.
However, if I put a common package in to both plugins, that package must be identical and have the exact full pathname for where it was compiled from. To accommodate this, I use a docker container to do my builds so that I can force the pathnames to always be correct for any common containers across my plugins.
I did say this was ugly, but it does work. If there is an import cycle because a type in one package uses a type in another package that then tries to use a type from the first package, the approach is to do a plugin that erases both types with interface{}. You can then make method and function calls back and forth doing the casting on the receiving side as needed.
In summary:
Use interface{} to make void pointers (that is, untyped).
Use the Cast() to force them to a pointer type that matches the underlying pointer. Use the plugin type localization so that types in the package main in separate plugins, and in the main program do not conflict If you use a common package between plugins, the path must be identical for all built plugins and the main program. Use the plug package to load the plugins, and exchange function pointers
For one of my issues I'm actually calling from a package in the main program out to a plugin, just to be able to call back to another package in the main program, avoiding the import cycle between the two packages. I ran in to this problem using the json and gob packages with custom marshaller methods. I use the types that are custom marshalled both in my main program, and in other plugins, while at the same time, I want the plugins to be built independent of the main program. I accomplish this by using a package for json and gob encode/decode custom methods that is included both in the main program and the plugins. However, I needed to be able to call back to the main program from the encoder methods, which gave me the import cycle type conflict. The above solution with another plugin specifically to solve the import cycle works. It does create an extra function call, but I have yet to see any other solution to this.
Hope this helps with this issue.
A shorter answer to your question (using interface), that does not take away the correctness and completeness of the other answers, is this example:
UserService is causing cyclic import, where it should not really be called from AuthorizationService. It's just there to be able to extract the user details, so we can declare only the desired functionality in a separated receiver-side interface UserProvider:
https://github.com/tzvatot/cyclic-import-solving-exaple/commit/bc60d7cfcbd4c3b6540bdb4117ab95c3f2987389
Basically, extracting an interface that contains only the required functionality on the receiver side, and use it instead of declaring a dependency on something external.

How to import package by path from string in Go?

I have a string with name of package (like "my/package/test") and I wanna import that and call some function from package.
Something like this:
func init() {
var pkg string = "test/my/pkg"
import pkg
pkg.Test()
}
PS. Thanks for help
The Go language does not allow what you mentioned in your example. This is a conscious choice. In my opinion, the reason behind this choice has to do with compiler performance and ease of code understanding by the machine. This for example enables tools such as gofix that can partially fix Go code without need for user intervention.
It also enables a programmer to clearly see all of the statically imported packages used by the program.
See also the grammar rules for source file organization in the Go language specification.
In relation to dynamically loading packages at run-time: Go has no support for loading packages at run-time. A future Go run-time might implement this feature (for example, it is occasionally being requested in messages in the golang-nuts mailing list), but the current state is that there is no support for this feature.
That's not possible in Go. The linker has to know the dependencies at compile-time, your string (and the init-function) are however evaluated at run-time. Also note, that parts of your programs which are not used, i.e. everything which isn't referred explicitly, wont even be part of the final binary - so reflection is not possible either.
If you need something like that, you have to manage the mapping on your own. You can for example use a global map in one package and use the init functions in the other packages to register the relevant functions, by adding them to the map. After that, you can use the map to do your look-ups dynamically.
Take a look at the http package for example. In a fictional blog package you might use the blog.init() function to register a couple of http handlers using the http.HandleFunc(pattern, handler) function. The main package then might call http.ListenAndServe() which looks up the right handlers at run-time.

Resources