CloudFlare suffered a massive security issue affecting all of its customers, including Rosetta Code. All passwords not changed since February 19th 2017 have been expired, and session cookie longevity will be reduced until late March.--Michael Mol (talk) 05:15, 25 February 2017 (UTC)

Reflection/Get source

From Rosetta Code
Task
Reflection/Get source
You are encouraged to solve this task according to the task description, using any language you may know.
Task

The goal is to get the source code or file path and line number where a programming object (e.g. module, class, function, method) is defined.

FreeBASIC[edit]

FreeBASIC is a fully compiled language which does not support reflection as such.

Nevertheless, the language does have a number of built-in macros which can be used to map certain entities back to the source code file. This is mainly useful for debugging purposes. Here's a simple example :

' FB 1.05.0 Win64 (getsource.bas)
 
Sub Proc()
Print __Function__ & " is defined in " & __Path__ & "\" & __File__ & " at line " & ( __line__ - 1)
End Sub
 
Proc()
Sleep
Output:
PROC is defined in c:\FreeBasic\getsource.bas at line 3

J[edit]

Source code which when executed will recreate the definition can be obtained using 5!:5 <'name' where name is the name of the thing you want source code for. Or, you can use 5!:6 which will provide a "fully parenthesized" variant for the tacit part of any definition.

You can also use 4!:4 and 4!:3 to find the file containing the name's definition (if there is one). Line number is not tracked.

Examples:

   mean=:+/ %#
5!:5 <'mean'
+/ % #
5!:6 <'mean'
(+/) % #
4!:4 <'mean'
_1
4!:4 <'names'
2
2 { 4!:3 ''
┌────────────────────────────────────────────┐
│/Applications/j64-804/system/main/stdlib.ijs│
└────────────────────────────────────────────┘

We could also provide convenience functions for these mechanisms:

   linrep=: 5!:5@<
srcfile=: (4!:4@<) { a:,~ 4!:3 bind ''

Example use:

   linrep 'names'
[email protected]
srcfile 'names'
┌────────────────────────────────────────────┐
│/Applications/j64-804/system/main/stdlib.ijs│
└────────────────────────────────────────────┘
srcfile 'mean'
┌┐
││
└┘

Note that these mechanisms can be disabled (using 3!:6).

JavaScript[edit]

Function.toString() will return the source code for user-defined functions.

function foo() {...}
foo.toString();
// "function foo() {...}"
 

For native functions, the function body typically will be a syntactically invalid string indicating the function is native. This behavior isn't part of any ECMAScript standard, but is common practice.

Math.sqrt.toString();
// "function sqrt() { [native code] }"
 

Lingo[edit]

Lingo does not allow to identify specific line numbers (automatically), but you can get the full source code of the script which defines either a class or a global function. Class scripts (called "parent scripts") only define a single class, so no additional parsing needed. Global functions are defined in movie scripts, there can be any number of such movie scripts, but in each movie script all function names must be unique. So it's not too hard to manually find the line number for a specific function in the returned code (e.g. using a RegExp).

----------------------------------------
-- Returns source code either for a class (parent script) or a class instance (object)
-- @param {script|instance} class
-- @return {string}
----------------------------------------
on getClassCode (class)
if ilk(class)=#instance then class=class.script
return class.text
end
 
----------------------------------------
-- Returns the source code of the movie script that defines the specified global function
-- @param {symbol} func - function specified as symbol
-- @return {string|VOID}
----------------------------------------
on getGlobalFunctionCode (func)
-- iterate over all members in all castlibs
repeat with i = 1 to _movie.castlib.count
repeat with j = 1 to _movie.castlib[i].member.count
m = _movie.castlib[i].member[j]
if m.type<>#script then next repeat
if m.scriptType=#movie and m.script.handler(func) then return m.script.text
end repeat
end repeat
end

Usage:

obj = script("MyClass").new()
put getClassCode(obj)
-- script text is printed...
 
func = #startMovie
put getGlobalFunctionCode(func)
-- script text is printed...

Perl 6[edit]

Works with: rakudo version 2016.11


A full path is provided for built-in routines/methods. However for routines exported by pre-compiled modules a precompilation hash is returned, not a proper file path.

say &sum.file;
say Date.^find_method("day-of-week").file;
Output:
SETTING::src/core/Any.pm
SETTING::src/core/Dateish.pm

Python[edit]

Modules loaded from files have a __file__ attribute.

import os
os.__file__
# "/usr/local/lib/python3.5/os.pyc"
 

Ruby[edit]

Method#source_location will return the file and line number of a Ruby method. If a method wasn't defined in Ruby, Method#source_location returns nil.

require 'mathn'
Math.method(:sqrt).source_location
# ["/usr/local/lib/ruby2.3/2.3.0/mathn.rb", 119]
 
Class.method(:nesting).source_location
# nil, since Class#nesting is native
 

zkl[edit]

Reads the source file and counts the lines.

src:=File(__FILE__).read();
println("Src file is \"%s\" and has %d lines".fmt(__FILE__,src.len(1)));
Output:
$ zkl foo
Src file is "foo.zkl" and has 2 lines