reflectx

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 7, 2026 License: MIT Imports: 4 Imported by: 0

README

Go package reflectx provides generic helpers built on reflect and runtime

License MIT Go version Test Coverage Status Go Report Card Release Go Reference

Documentation

Overview

Package reflectx provides generic helpers built on reflect and runtime, such as listing an interface's methods and resolving the caller's function/method name or package name from the call stack.

The Caller* functions — CallerPkg, CallerPkgPath, CallerMethodName, CallerFuncName, CallerTypeMethodName — examine the program counter of the calling function by using runtime.Caller. Each accepts a skip parameter that controls how many stack frames to ascend:

  • 0 = the immediate caller of the Caller* function
  • 1 = the caller's caller, and so on.

Panic behavior:

  • CallerMethodName and CallerTypeMethodName panic when the caller is a top-level function (no receiver type). They are designed for use inside methods.
  • CallerFuncName handles both functions and methods without panicking.
  • CallerPkg and CallerPkgPath panic if the call stack entry is malformed — this should never happen in practice.
  • MethodsOf panics when v is not a pointer to an interface.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func CallerFuncName

func CallerFuncName(skip int) string

CallerFuncName returns the function or method name of the caller at the given stack depth. Unlike CallerMethodName, it works for both top-level functions and methods without panicking.

func CallerMethodName

func CallerMethodName(skip int) string

CallerMethodName returns the method name of the caller at the given stack depth. For a method "pkg.Type.Method" it returns "Method". For a closure "pkg.Type.Method.func1" it returns "Method". It panics if the caller is a top-level function.

Example

ExampleCallerMethodName shows how to capture the calling method's name without passing it explicitly through the call chain.

This is used e.g. by transaction wrappers (NoTx/Tx) to tag every DAL error with the name of the repository method that triggered it.

package main

import (
	"context"
	"fmt"

	"github.com/powerman/reflectx"
)

// exampleService demonstrates how a production service would use CallerMethodName
// and CallerTypeMethodName to tag errors or logs with the method name
// without explicit configuration at each call site.
type exampleService struct{}

func (exampleService) Create(_ context.Context) string {
	return fmt.Sprintf("%s: not found", reflectx.CallerMethodName(0))
}

func (exampleService) Get(_ context.Context) string {
	return reflectx.CallerTypeMethodName(0)
}

func main() {
	s := exampleService{}
	out := s.Create(context.Background())
	fmt.Println(out)
}
Output:
Create: not found

func CallerPkg

func CallerPkg(skip int) string

CallerPkg returns the package name of the caller at the given stack depth. For a function in "a/b/pkg.Func" it returns "pkg".

Example

ExampleCallerPkg shows how to detect the caller's package name from the call stack.

This is used e.g. by logging middleware factories (MakeUnaryServerLogger, MakeStreamServerLogger) that need to know which package created them so each service's logs are attributed automatically.

package main

import (
	"fmt"

	"github.com/powerman/reflectx"
)

func main() {
	// In a real application the returned value would be something like
	// "repo", "auth", "grpcx" — the name of the calling package.
	fmt.Println(reflectx.CallerPkg(0))
}
Output:
reflectx_test

func CallerPkgPath

func CallerPkgPath(skip int) string

CallerPkgPath returns the full package path of the caller at the given stack depth. For a function in "a/b/pkg.Func" it returns "a/b/pkg".

func CallerTypeMethodName

func CallerTypeMethodName(skip int) string

CallerTypeMethodName returns the "Type.Method" name of the caller at the given stack depth, with any pointer-receiver parentheses stripped (e.g. "(*T).M" becomes "T.M"). For a closure it returns "EnclosingType.EnclosingMethod". It panics if the caller is a top-level function.

Example

ExampleCallerTypeMethodName shows how to capture the "Type.Method" string from the call stack, with any pointer-receiver parentheses stripped.

This is used e.g. by middleware factories to identify exactly which service method is being invoked, without manual method-name wiring.

package main

import (
	"context"
	"fmt"

	"github.com/powerman/reflectx"
)

// exampleService demonstrates how a production service would use CallerMethodName
// and CallerTypeMethodName to tag errors or logs with the method name
// without explicit configuration at each call site.
type exampleService struct{}

func (exampleService) Create(_ context.Context) string {
	return fmt.Sprintf("%s: not found", reflectx.CallerMethodName(0))
}

func (exampleService) Get(_ context.Context) string {
	return reflectx.CallerTypeMethodName(0)
}

func main() {
	s := exampleService{}
	method := s.Get(context.Background())
	fmt.Println(method)
}
Output:
exampleService.Get

func MethodsOf

func MethodsOf(v any) []string

MethodsOf returns the names of all methods of the interface v points to. v must be a pointer to an interface, e.g. new(Service).

Example

ExampleMethodsOf shows how to enumerate all methods of an interface.

This is useful for pre-registering Prometheus metric label dimensions before any requests arrive, so every requested label combination is populated from the start.

package main

import (
	"context"
	"fmt"

	"github.com/powerman/reflectx"
)

func main() {
	type Service interface {
		Create(ctx context.Context, _ any) error
		Get(ctx context.Context, _ int64) (any, error)
		Delete(ctx context.Context, _ int64) error
	}

	for _, name := range reflectx.MethodsOf(new(Service)) {
		fmt.Println(name)
	}
}
Output:
Create
Delete
Get

Types

This section is empty.

Jump to

Keyboard shortcuts

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