How to Determine the Namespace of a Function

How do you determine the namespace of a function?

I very recently learned about find() which seems to do just this.

R> find("ls")
[1] "package:base"
R> find("na.locf")
[1] "package:zoo"

Get namespace of function

You can use getAnywhere For example, if you're looking for the namespace for the stringr function str_locate you can do

getAnywhere("str_locate")$where
# [1] "package:stringr" "namespace:stringr"

This will work as long as stringr is "visible on the search path, registered as an S3 method or in a namespace but not exported."

The result is a named list, and you can see what's available from getAnywhere with names

names(getAnywhere("str_locate"))
# [1] "name" "objs" "where" "visible" "dups"

How to access the namespace of a function in python

The way you're calling the code, there's not a good way to get at that number. But if you saved the instance of function_creator to a variable, you'd be able to get at it more easily:

fc = function_creator(5)
f = fc.getfunc()

f()
print(fc.number)

While I said there isn't an good way to access the value, it is possible by diving into the internals of the function object, as the function is a closure on the self variable from getfunc. You can get the value of that self argument from f using f.__closure__[0].cell_contents, and then get the number by checking its number attribute:

f = function_creator(5).getfunc()
f()

fc = f.__closure__[0].cell_contents
print(fc.number)

This is CPython specific, and probably won't work in other Python interpreters.

Determine what namespace the function was called in


What you are looking for is : ReflectionFunctionAbstract::getNamespaceName

If you want to know where you're coming from debug_backtrace() is your friend.

The following should solve your puzzle:

function backtrace_namespace() 
{
$trace = array();
$functions = array_map(
function ($v) {
return $v['function'];
},
debug_backtrace()
);
foreach ($functions as $func) {
$f = new ReflectionFunction($func);
$trace[] = array(
'function' => $func,
'namespace' => $f->getNamespaceName()
);
}
return $trace;
}

Just call it from anywhere to see the backtrace.
I modified your "procedural" code file as follows:

namespace Foo;

function bar ()
{
var_export(backtrace_namespace());
}

/** The unasked question: We need to use the fully qualified name currently. */
function go()
{
\Site\Action\add('hookname', 'Foo\\bar');
}

go();

The Result from including this file will be the following on stdout:

array (
0 =>
array (
'function' => 'backtrace_namespace',
'namespace' => '',
),
1 =>
array (
'function' => 'Foo\\bar',
'namespace' => 'Foo',
),
2 =>
array (
'function' => 'call_user_func',
'namespace' => '',
),
3 =>
array (
'function' => 'Site\\Action\\add',
'namespace' => 'Site\\Action',
),
4 =>
array (
'function' => 'Foo\\go',
'namespace' => 'Foo',
),
)

Now for bonus points the answer to the hidden question:

How do I resolve the calling namespace to avoid using fully qualified function name as argument?

The following will allow you to call the function as you intended:

 Site\Action\add('hookname', 'bar');

Without getting the dreaded:

Warning: call_user_func() expects parameter 1 to be a valid callback, function 'bar' not found or invalid function name

So before you redesign try this on for size:

namespace Site\Action;

function add($hook, $function)
{
$trace = backtrace_namespace();
$prev = (object) end($trace);

$function = "$prev->namespace\\$function";

if (is_callable($function))
call_user_func($function);
}

I see no reason why debug_backtrace should not be used, this is what it is there for.

nJoy!

How to check if a namespaced function exists?

I used this instead:

function getProperty(objName) {
var parts = objName.split('.');
for (var i = 0, length = parts.length, obj = window; i < length; ++i) {
obj = obj[parts[i]];
}
return obj;
}

Got it here: Access namespaced javascript object by string name without using eval

Get reference to a namespace where the function was called

Yes you can with the inspect module, example:

test.py

import os
import sys
import inspect

def my_function():
print ('Module/Function : ' + os.path.basename(__file__) + ' ' + sys._getframe().f_code.co_name +'()')
print ('Called from : ' + os.path.basename(inspect.stack()[1][1]) +' ' + inspect.stack()[1][3] + '()' )

you can now import test from another module, and call the function.

test2.py

import test

def my_test_function():
test.my_function()

my_test_function()

output:

Module/Function : test.py my_function()
Called from : test.py <module>()
Module/Function : test.py my_function()
Called from : test2.py my_test_function()

the first two are during import, the last two output lines are when you call them from test2.py

How to access a function within a namespace

You need to declare an instance of the Class that contains the function

namespace.classname YourClass = new namespace.classname();

then you can use the function as follows

YourClass.functionname();

If you want to be able to use the function without declaring an instance of the class it needs to be a static funciton.

C++ can't find function out of namespace

This is a kind of name hiding; functions/operators can't be overloaded through different scopes.

According to the rule of name lookup,

(emphasis mine)

..., name lookup examines the scopes as described below, until it finds at least one declaration of any kind, at which time the lookup stops and no further scopes are examined.

For this case, the name operator<< is found at the scope of namespace my (i.e. itself), then name lookup stops, the global scope won't be examined, the global operator<< won't be considered for the following overload resolution.

And

Observation 1: If the two functions differ in name, no error occurs.

It's fine because there's no name hiding.

Observation 2: If namespace my { } is removed, no error occurs.

It's fine because the two operator<< is put at the same scope, i.e. the global namespace. Then both operator<< could be found and then considered at overload resolution, the appropriate one will be selected at last.

As the comments suggested, you can apply using to introduce the names in global namespace into namespace my; then both operator<< will be found and then considered in overload resolution.

Is there a way to automatically find which c++ namespace a method belongs to in gdb?

Using this question and its answers as hints, you might use e.g. info functions getTranslation, and it should list all functions named getTranslation complete with the classes/namespaces.



Related Topics



Leave a reply



Submit