Reflection/Get source: Difference between revisions
m
→{{header|Wren}}: Minor tidy
(added Perl programming solution) |
m (→{{header|Wren}}: Minor tidy) |
||
(3 intermediate revisions by 3 users not shown) | |||
Line 12:
Such a printing routine would work best if it substituted the null terminator for $60 (the <code>RTS</code> instruction.) This would only print the bytecode for the routine. Conversion to assembly language would need to be done separately.
<
sta $00
LDA #>foo
Line 44:
Terminated:
jsr PrintHex ;print the last instruction of the routine.
rts</
There is no way to get the file name that the routine is stored in. Whether you use a linker or <code>include</code> statements, this information is lost by the time the code is assembled into an executable form.
Line 50:
=={{header|Clojure}}==
<
; Use source function for source code.
(source println)
; Use meta function for filenames and line numbers (and other metadata)
(meta #'println)</
=={{header|Factor}}==
Printing definitions:
<
\ integer see ! class
nl
\ dip see ! word</
{{out}}
<pre>
Line 72:
</pre>
Obtaining the code that makes up a word as a quotation (an anonymous function/collection that stores code):
<
\ partition def>> .</
{{out}}
<pre>
Line 79:
</pre>
Obtaining the vocabulary name a word belongs to:
<
\ dip vocabulary>> print</
{{out}}
<pre>
Line 86:
</pre>
Obtaining file paths for a particular vocabulary:
<
"sequences" vocab-files .</
{{out}}
<pre>
Line 97:
</pre>
Obtaining the path and line number where a word is defined:
<
{{out}}
<pre>
Line 109:
This is mainly useful for debugging purposes. Here's a simple example :
<
Sub Proc()
Line 116:
Proc()
Sleep</
{{out}}
Line 125:
=={{header|Go}}==
It is possible to get the file name/path and line number of a given function in Go as follows.
<
import (
Line 146:
fmt.Println("Name of file :", path.Base(file))
fmt.Println("Line number :", line)
}</
{{out}}
Line 163:
Examples:
<
5!:5 <'mean'
+/ % #
Line 175:
┌────────────────────────────────────────────┐
│/Applications/j64-804/system/main/stdlib.ijs│
└────────────────────────────────────────────┘</
We could also provide convenience functions for these mechanisms:
<
srcfile=: (4!:4@<) { a:,~ 4!:3 bind ''</
Example use:
<
list_z_@nl
srcfile 'names'
Line 193:
┌┐
││
└┘</
Note that these mechanisms can be disabled (using [http://www.jsoftware.com/help/dictionary/dx003.htm 3!:6]).
Line 203:
Note that the file name is not the absolute path on the file system, but is relative to the java CLASSPATH.
<syntaxhighlight lang="java">
public class ReflectionGetSource {
Line 233:
}
</syntaxhighlight>
{{out}}
<pre>
Line 260:
<code>Function.toString()</code> will return the source code for user-defined functions.
<
foo.toString();
// "function foo() {...}"
</syntaxhighlight>
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.
<
// "function sqrt() { [native code] }"
</syntaxhighlight>
=={{header|Julia}}==
{{works with|Julia|0.6}}
<
function foo() end
@which foo() # where foo is defined
@less foo() # first file where foo is defined</
=={{header|Kotlin}}==
Line 286:
2. In the example below the ''hello'' function will actually be referred to as ''_.hello'' in the generated JavaScript from within the main() function.
<
fun hello() {
Line 296:
println(code)
}
</syntaxhighlight>
{{out}}
Line 312:
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
Line 336:
end repeat
end repeat
end</
Usage:
<
put getClassCode(obj)
-- script text is printed...
Line 344:
func = #startMovie
put getGlobalFunctionCode(func)
-- script text is printed...</
=={{header|Lua}}==
Introspective capabilities are provided by the debug library..
<
function foo(bar)
info = debug.getinfo(1)
for k,v in pairs(info) do print(k,v) end
end
foo()</
{{out}}
<pre>linedefined 2
Line 371:
=={{header|Nanoquery}}==
If a program is run from the command line, the absolute path of the source file will be stored in __file__ as a string.
<
println new(File, __file__).readAll()</
=={{header|Nim}}==
<
proc f(arg: int): int = arg+1
Line 387:
proc g(arg: float): float = arg*arg
getSource(staticRead(currentSourcePath()))</
{{out}}
<pre>source of procedure f is:
Line 400:
=={{header|Perl}}==
<
use strict;
Line 408:
print Class::Inspector->resolved_filename( 'IO::Socket::INET' ), "\n";
</syntaxhighlight>
{{out}}
<pre>/home/hkdtam/perl5/perlbrew/perls/perl-5.30.0/lib/5.30.0/x86_64-linux/IO/Socket/INET.pm
Line 443:
=={{header|Python}}==
Modules loaded from files have a <code>__file__</code> attribute.
<
os.__file__
# "/usr/local/lib/python3.5/os.pyc"
</syntaxhighlight>
=={{header|Raku}}==
Line 455:
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.
<syntaxhighlight lang="raku"
say Date.^find_method("day-of-week").file;</
{{out}}
Line 466:
=={{header|REXX}}==
This REXX version was modeled after the '''zkl''' example, but in addition, it also displays the source.
<
/*───────────────────────── displays the number of lines. */
#=sourceline()
Line 477:
say 'The name of the source file (program) is: ' sID
say 'The number of lines in the source program: ' #
/*stick a fork in it, we're all done.*/</
{{out|output|:}}
<pre>
Line 498:
=={{header|Ring}}==
<
# Project : Reflection/Get source
Line 526:
end
fclose(fp)
</syntaxhighlight>
Output:
<pre>
Line 535:
=={{header|Ruby}}==
<code>[http://ruby-doc.org/core/Method.html#method-i-source_location Method#source_location]</code> will return the file and line number of a Ruby method. If a method wasn't defined in Ruby, <code>Method#source_location</code> returns nil.
<
Math.method(:sqrt).source_location
# ["/usr/local/lib/ruby2.3/2.3.0/mathn.rb", 119]
Line 541:
Class.method(:nesting).source_location
# nil, since Class#nesting is native
</syntaxhighlight>
=={{header|Smalltalk}}==
You can ask a class for a method:
<syntaxhighlight lang="smalltalk">mthd := someClass compiledMethodAt:#nameOfMethod</syntaxhighlight>
and a method for its source:
<syntaxhighlight lang="smalltalk">mthd source</syntaxhighlight>
or better yet, you can ask any active stack frame for its method, source and line number (what is the line number of the "current PC" if you like):
<syntaxhighlight lang="smalltalk">thisContext method source
thisContext lineNumber</syntaxhighlight>
so, a Logger could (actually: does) print a log-message with:
Stderr print: e'{msg} generated in {thisContext sender selector} line: {thisContext sender lineNumber}'.
Stderr print: e'generated by the following source line: {thisContext sender method source asStringCollection at:thisContext sender lineNumber}'.
=={{header|Tcl}}==
Tcl's <tt>info</tt> command makes it possible to access the source of nearly anything. This example can show the source code of any proc. The popular <b>tkcon</b> includes a <tt>dump</tt> command which is capable of showing aliases, arrays and more .. and a <tt>edit</tt> command which lets you edit them in an interactive window!
<
set name [uplevel 1 [list namespace which -command $name]]
set args [info args $name]
Line 560 ⟶ 573:
}
puts [getproc getproc]</
{{out}}
Note the output differs very slightly from the original source: the procedure's name is fully namespace-qualified, and the arguments are in "canonical list form", which does not include braces in this simple case.
<
set name [uplevel 1 [list namespace which -command $name]]
set args [info args $name]
Line 577 ⟶ 590:
set body [info body $name]
list proc $name $args $body
}</
=={{header|Wren}}==
{{libheader|Wren-pattern}}
Wren doesn't have reflection as such but the command line version (Wren CLI) does have an easy way to obtain a script's own source code which can then be searched for where an object is defined
<
import "io" for File
import "/.pattern" for Pattern
var getSourceLines = Fn.new {
Line 612 ⟶ 625:
System.print("File name : %(fileName)")
System.print("Function name : %(funcName)")
System.print("Line number : %(found > 0 ? found : "Function not found")")</
{{out}}
<pre>
File name :
Function name : getSourceLines
Line number : 5
Line 623 ⟶ 636:
=={{header|zkl}}==
Reads the source file and counts the lines.
<
println("Src file is \"%s\" and has %d lines".fmt(__FILE__,src.len(1)));</
{{out}}
<pre>
|