ansariBE
ansariBE

Reputation: 45

How to find a procedure by using the code inside the proc?

Is it possible to find the procedure name by using the content of that procedure?

For example,

proc test {args} {
    set varA "exam"
    puts "test program"
}

Using the statement set varA, is it possible to find its procedure name test?

Because, I need to find a procedure for which i know the output [it's printing something, i need to find the procedure using that].

I tried many ways like info frame, command. But, nothing helps.

Upvotes: 0

Views: 273

Answers (2)

Donal Fellows
Donal Fellows

Reputation: 137557

Is it possible to find the procedure name by using the content of that procedure?

Yes. You use info level 0 to get the argument words to the current procedure (or info level -1 to get its caller's argument words). The first word is the command name, as resolved in the caller's context. That might be enough, but if not, you can use namespace which inside an uplevel 1 to get the fully-qualified name.

proc foo {args} {
    set name [lindex [info level 0] 0]
    set FQname [uplevel 1 [list namespace which $name]]
    # ...
}

Note that this does not give you the main name in all circumstances. If you're using aliases or imported commands, the name you'll get will vary. Mostly that doesn't matter too much.

Upvotes: 1

Dinesh
Dinesh

Reputation: 16428

With info proc, we can get the content of a procedure which may helps you in what you expect.

The following procedure will search for the given word in all the namespaces. You can change it to search in particular namespace as well. Also, the search word can also be case insensitive if altered in terms of regexp with -nocase. It will return the list of procedure names which contains the search word.

proc getProcNameByContent {searchWord} {
    set resultProcList {}
    set nslist [namespace children ::]; # Getting all Namespaces list
    lappend nslist ::; # Adding 'global scope namespace as well 

    foreach ns $nslist {
        if {$ns eq "::"} {
            set currentScopeProcs [info proc $ns*]
        } else {
            set currentScopeProcs [info proc ${ns}::*]
        }

        foreach myProc $currentScopeProcs  {
            if {[regexp $searchWord [info body $myProc]]} {
                puts "found in $myProc"
                lappend resultProcList $myProc
            }
        }
    }
    return $resultProcList
}

Example

% proc x {} {
        puts hai
}
% proc y {} {
        puts hello
}
% proc z {} {
        puts world
}
% namespace eval dinesh {
        proc test {} {
                puts "world is amazing"
        }
}
%
% getProcNameByContent world
found in ::dinesh::test
found in ::z
::dinesh::test ::z
%

Upvotes: 0

Related Questions