g | x | w | all
Bytes Lang Time Link
nan170614T235743Zsergiol
nan170617T051822ZAndrei O
nan170616T164759Zdarrylye
nan170622T153527Zfergusq
nan170614T135038ZShaggy
nan170621T145210ZChristop
nan170615T041410ZTitus
nan170614T141612ZJör
nan170615T025603ZTessella
nan170615T020422ZPoke
002Python170614T130454ZDead Pos
002Python170614T134257Ztotallyh
046Ruby170615T215807ZValue In
nan170615T125804Zmb7744
nan170614T131152ZTheLetha
nan170614T214526Zuser6213
nan170614T125607ZJungHwan
nan170614T132212Zflawr
nan170614T125743ZMartin E

Tcl

proc p a {puts [subst $a]}

Try it online!

PowerShell

New version but works starting from PowerShell 3.0

function p{[scriptblock]::create($myinvocation.line).ast.findall({$args[0]-is[Management.Automation.Language.VariableExpressionAst]},0)[0]|% v*h|% u*|%{($_,!1)[!$_]}}

Try It Online!

Previous version

function p{$t=[management.automation.psparser]::tokenize($myinvocation.line,[ref]@())|? type -match '^[cv]'|? start|% content;($t,!1)[!$t]}

Try It Online!

JavaScript (ES6)

For all property names in window (Object.getOwnPropertyNames(w)), attempt to define a getter for that property that returns the property name.

Then, add an entry to a Map M where the key is the (possibly overridden) value of the property, and the value is the name of the property.

The function f simply takes a variable (i.e. a property of window) and returns the entry in M for that value.

let
    w = window,
    M = new Map(),
    L = console.log,
    P = Object.getOwnPropertyNames(w),
    D = Object.defineProperty

for(const p of P){
    try {
        D(w, p, {
            get(){
                return p
            }
        })
    } catch(e){ L(e) }

    try {
        M.set(w[p], p)
    } catch(e){ L(e) }
}

let f = v => M.get(v)

This works for all built-in global variables except window itself, as there is no way to distinguish it from top (unless run in a frame):

L( P.filter(p => p !== f(w[p])) )
// -> ['window']

Röda

f(&a...) {
	a() | name(_) | for str do
		false if [ "<" in str ] else [str]
	done
}

Try it online!

Röda has a builtin function for this – name. Unfortunately, though, it doesn't return a falsy value when not given a variable.

This code abuses several features of reference semantics. Explanation line by line:

f(&a...) {

The function takes a variable number of reference arguments (&a...). This is the only way in Röda to create a list of references.

a() | name(_) | for str do

At the second line the elements of a are pushed to the stream (a()). These elements are references if the function was given variables and normal values otherwise.

The elements are iterated using an underscore loop. The underscore syntax is syntax sugar for for loops, so name(_) is equivalent to name(var) for var. The name of the variable used in the for loop is of form <sfvN> where N varies. (Ie. "name(<sfv1>) for <sfv1>") It is illegal for a user-defined variable to contain < or >, so the generated names don't collide with existing variable names.

The name() function returns the name of the given variable. If the element in a being iterated is a reference, then it is the variable given to name. Otherwise, if the element was a normal value, the variable given to name is the underscore variable <sfvN>. This is due to the semantics of references in Röda: if a function accepts a reference and the function is passed a reference variable, the passed value does not point to the reference variable but to the variable the reference variable points to.

false if [ "<" in str ] else [str]

At the third line we examine if the variable name in the stream contains a < character. If so, it is an underscore variable and the value passed to f was not a reference. Otherwise we output the name of the reference.

This solution does not work if the variable given to the function is a reference or an underscore variable. However, the question specifies that only global variables must be handled, and they can't be references or underscore variables in Röda.

JavaScript (ES6)

Requires that the value of the variable passed to the function is unique to that variable. Returns undefined if a variable wasn't passed.

arg=>{
    for(key in this)
        if(this[key]===arg)
            return key
}

Try it

For some reason, it throws a cross-origin error in a Snippet when a "literal" is passed.

var fn=
    arg=>{
        for(key in this)
            if(this[key]===arg)
                return key
    },
str="string",
int=8,
arr=[1,2,3],
obj={a:1}
console.log(fn(fn))
console.log(fn(str))
console.log(fn(int))
console.log(fn(arr))
console.log(fn(obj))


Explanation

Loop through all the entries in the global object (this), checking if the value of each one is strictly equal to the value of the argument passed to the function. If a matching entry is found then its key (name) is returned, exiting the function.


Alternative

With the same requirements as above

arg=>
    [...Object.keys(this)].filter(key=>
        this[key]==arg
    ).pop()

PHP

While the other PHP submissions only test if the given value matches a value of a global, this version works by taking a reference to the value:

// take a reference to the global variable
function f(&$i){
  foreach(array_reverse($GLOBALS) as $key => $value)
    if($key != 'GLOBALS') {
      // Set the value of each global to its name
      $GLOBALS[$key] = $key;
    }

  foreach($GLOBALS as $key => $value)
    if($key != 'GLOBALS' && $key != $value) {
      // The values mismatch so it had a reference to another value
      // we delete it
      unset($GLOBALS[$key]);
      // and update the value to its name again
      $GLOBALS[$key] = $key;
    }

  echo '$', is_array($i) ? 'GLOBALS' : $i, "\n";
}

This should now work even if the global variable is a reference to another value at the time of calling.

Test it here.

PHP

function f($v){foreach($GLOBALS as$n=>$x)$x!=$v?:die($n);}

if value is found, print variable name and exit. print nothing and don´t exit else.

61 bytes to return variable name or NULL:

function f($v){foreach($GLOBALS as$n=>$x)if($x==$v)return$n;}

It will not find named functions, only those assigned to variables.
And a PHP function cannot detect wether a parameter was provided by reference or by value. The function will just return the first name where the value matches the function parameter value.

Test it online

PHP

Needs that the variable value is unique in the array of the global variables

function v($i){echo"$".array_search($i,$GLOBALS);}

Try it online!

PHP, 96 bytes

function v($i){
echo($i==end($g=$GLOBALS))?"$".key(array_slice($g,-1)):0;
}
$hello=4;
v($hello);

Try it online!

Needs that the variable is initialized directly to the function call.

Checks if the last global variable is equal surrendering variable

PowerShell

function t($t){(variable($MyInvocation.Line.Split(' $'))[-1]-ea si).Name}

$apple = 'hi'
t $apple
apple

t 3.141

But it doesn't work reliably, it's rudimentary.

Java

String getParamName(String param) throws Exception {
    StackTraceElement[] strace = new Exception().getStackTrace();
    String methodName = strace[0].getMethodName();
    int lineNum = strace[1].getLineNumber();

    String className = strace[1].getClassName().replaceAll(".{5}$", "");
    String classPath = Class.forName(className).getProtectionDomain().getCodeSource().getLocation().getPath() + className + ".class";

    StringWriter javapOut = new StringWriter();
    com.sun.tools.javap.Main.run(new String[] {"-l", "-c", classPath}, new PrintWriter(javapOut));
    List<String> javapLines = Arrays.asList(javapOut.toString().split("\\r?\\n"));
    int byteCodeStart = -1;
    Map<Integer, Integer> byteCodePointerToJavaPLine = new HashMap<Integer, Integer>();
    Pattern byteCodeIndexPattern = Pattern.compile("^\\s*(\\d+): ");
    for (int n = 0;n < javapLines.size();n++) {
        String javapLine = javapLines.get(n);
        if (byteCodeStart > -1 && (javapLine == null || "".equals(javapLine))) {
            break;
        }
        Matcher byteCodeIndexMatcher = byteCodeIndexPattern.matcher(javapLine);
        if (byteCodeIndexMatcher.find()) {
            byteCodePointerToJavaPLine.put(Integer.parseInt(byteCodeIndexMatcher.group(1)), n);
        } else if (javapLine.contains("line " + lineNum + ":")) {
            byteCodeStart = Integer.parseInt(javapLine.substring(javapLine.indexOf(": ") + 2));
        }
    }

    int varLoadIndex = -1;
    int varTableIndex = -1;
    for (int i = byteCodePointerToJavaPLine.get(byteCodeStart) + 1;i < javapLines.size();i++) {
        if (varLoadIndex < 0 && javapLines.get(i).contains("Method " + methodName + ":")) {
            varLoadIndex = i;
            continue;
        }

        if (varLoadIndex > -1 && javapLines.get(i).contains("LocalVariableTable:")) {
            varTableIndex = i;
            break;
        }
    }

    String loadLine = javapLines.get(varLoadIndex - 1).trim();
    int varNumber;
    try {
        varNumber = Integer.parseInt(loadLine.substring(loadLine.indexOf("aload") + 6).trim());
    } catch (NumberFormatException e) {
        return null;
    }
    int j = varTableIndex + 2;
    while(!"".equals(javapLines.get(j))) {
        Matcher varName = Pattern.compile("\\s*" + varNumber + "\\s*([a-zA-Z_][a-zA-Z0-9_]*)").matcher(javapLines.get(j));  
        if (varName.find()) {
            return varName.group(1);
        }
        j++;
    }
    return null;
}

This currently works with a few gotchas:

  1. If you use an IDE to compile this it might not work unless it is run as Admin (depending on where the temporary class files are saved)
  2. You must compile using javac with the -g flag. This generates all debugging information including local variable names in the compiled class file.
  3. This uses an internal Java API com.sun.tools.javap which parses the bytecode of a classfile and produces a human readable result. This API is only accessible in the JDK libraries so you must either use the JDK java runtime or add tools.jar to your classpath.

This should now work even if the method is called multiple times in the program. Unfortunately it does not yet work if you have multiple invocations on a single line. (For one that does, see below)

Try it online!


Explanation

StackTraceElement[] strace = new Exception().getStackTrace();
String methodName = strace[0].getMethodName();
int lineNum = strace[1].getLineNumber();

String className = strace[1].getClassName().replaceAll(".{5}$", "");
String classPath = Class.forName(className).getProtectionDomain().getCodeSource().getLocation().getPath() + className + ".class";

This first part gets some general information about what class we're in and what the name of the function is. This is accomplished by creating an exception and parsing the first 2 entries of the stack trace.

java.lang.Exception
    at E.getParamName(E.java:28)
    at E.main(E.java:17)

The first entry is the line that the exception is thrown on which we can grab the methodName from and the second entry is where the function was called from.

StringWriter javapOut = new StringWriter();
com.sun.tools.javap.Main.run(new String[] {"-l", "-c", classPath}, new PrintWriter(javapOut));

In this line we are executing the javap executable that comes with the JDK. This program parses the class file (bytecode) and presents a human-readable result. We'll use this for rudimentary "parsing".

List<String> javapLines = Arrays.asList(javapOut.toString().split("\\r?\\n"));
int byteCodeStart = -1;
Map<Integer, Integer> byteCodePointerToJavaPLine = new HashMap<Integer, Integer>();
Pattern byteCodeIndexPattern = Pattern.compile("^\\s*(\\d+): ");
for (int n = 0;n < javapLines.size();n++) {
    String javapLine = javapLines.get(n);
    if (byteCodeStart > -1 && (javapLine == null || "".equals(javapLine))) {
        break;
    }
    Matcher byteCodeIndexMatcher = byteCodeIndexPattern.matcher(javapLine);
    if (byteCodeIndexMatcher.find()) {
        byteCodePointerToJavaPLine.put(Integer.parseInt(byteCodeIndexMatcher.group(1)), n);
    } else if (javapLine.contains("line " + lineNum + ":")) {
        byteCodeStart = Integer.parseInt(javapLine.substring(javapLine.indexOf(": ") + 2));
    }
}

We're doing a couple different things here. First, we are reading the javap output line by line into a list. Second we are creating a map of bytecode line indexes to javap line indexes. This helps us later to determine which method invocation we want to analyze. Finally we are using the known line number from the stack trace to determine which bytecode line index we want to be looking at.

int varLoadIndex = -1;
int varTableIndex = -1;
for (int i = byteCodePointerToJavaPLine.get(byteCodeStart) + 1;i < javapLines.size();i++) {
    if (varLoadIndex < 0 && javapLines.get(i).contains("Method " + methodName + ":")) {
        varLoadIndex = i;
        continue;
    }

    if (varLoadIndex > -1 && javapLines.get(i).contains("LocalVariableTable:")) {
        varTableIndex = i;
        break;
    }
}

Here we are iterating over the javap lines one more time in order to find the spot where our method is being invoked and where the Local Variable Table starts. We need the line where the method is invoked because the line before it contains the call to load the variable and identifies which variable (by index) to load. The Local Variable Table helps us actually look up the name of the variable based on the index we grabbed.

String loadLine = javapLines.get(varLoadIndex - 1).trim();
int varNumber;
try {
    varNumber = Integer.parseInt(loadLine.substring(loadLine.indexOf("aload") + 6).trim());
} catch (NumberFormatException e) {
    return null;
}

This part is actually parsing the load call to get the variable index. This can throw an exception if the function isn't actually called with a variable so we can return null here.

int j = varTableIndex + 2;
while(!"".equals(javapLines.get(j))) {
    Matcher varName = Pattern.compile("\\s*" + varNumber + "\\s*([a-zA-Z_][a-zA-Z0-9_]*)").matcher(javapLines.get(j));  
    if (varName.find()) {
        return varName.group(1);
    }
    j++;
}
return null;

Finally we parse out the name of the variable from the line in the Local Variable Table. Return null if it isn't found although I've seen no reason why this should happen.

Putting it all together

 public static void main(java.lang.String[]);
    Code:
...
      18: getstatic     #19                 // Field java/lang/System.out:Ljava/io/PrintStream;
      21: aload_1
      22: aload_2
      23: invokevirtual #25                 // Method getParamName:(Ljava/lang/String;)Ljava/lang/String;
...
    LineNumberTable:
...
      line 17: 18
      line 18: 29
      line 19: 40
...
    LocalVariableTable:
      Start  Length  Slot  Name   Signature
          0      83     0  args   [Ljava/lang/String;
          8      75     1     e   LE;
         11      72     2   str   Ljava/lang/String;
         14      69     3  str2   Ljava/lang/String;
         18      65     4  str4   Ljava/lang/String;
         77       5     5    e1   Ljava/lang/Exception;

This is basically what we're looking at. In the example code the first invocation is line 17. line 17 in the LineNumberTable shows that the beginning of that line is bytecode line index 18. That is the System.out load. Then we have aload_2 right before the method call so we look for the variable in slot 2 of the LocalVariableTable which is str in this case.


For fun, here's one which handles multiple function calls on the same line. This causes the function to not be idempotent but that's kind of the point. Try it online!

Python 2

Some research has been done. And it seems to be possible in python, but I still expect some troubles to be found.
Solution is not perfect, as it assumes some structure of the code. Yet I didn't break it still.

import inspect
import re

def get_name(var):
    called = inspect.getouterframes(inspect.currentframe())[1][4][0]
    return re.search('(?<=get_name\().*(?=\))', called).group().lstrip().rstrip()

This uses inspect to look at surround scope and find where function get_name is called. For example inspect...[1] will return

(< frame object at 0x01E29030>, 'C:/Users/---/PycharmProjects/CodeGolf/Name_var.py', 14, '< module>', ['print get_name( a )\n'], 0)

And inspect...[1][4] will show us list with code, where function is called:

['print get_name( a )\n']

After that I used regex to retrieve name of the argument

re.search('(?<=get_name\().*(?=\))', called).group()

And .lstrip().rstrip() to remove all whitespaces that may be placed into bracets.

Example with some tricky input

Python 2

This is about the most dirty code I've written but it works. ¯\_(ツ)_/¯ Throws an error on a non-existent variable as Python will immediately dislike you for calling the function with one. Also throws an error on non-variables but this can be fixed with a try/except if needed.

import inspect
import re

def name_of(var):
    for i in inspect.getframeinfo(inspect.currentframe().f_back)[3]:
        return re.search(r'\bname_of\s*\(\s*([A-Za-z_][A-Za-z0-9_]*)\s*\)', i).groups()[0]

Try it online!

If we're allowed to take the argument as a string, this satisfies the requirements of outputting a falsy value on an invalid input.

import inspect
import re

def name_of(var):
    # return var :P

    try:
        eval(var)
    except NameError:
        return False

    for i in inspect.getframeinfo(inspect.currentframe().f_back)[3]:
        try:
            return re.search(r'\bname_of\s*\(\s*[\'"]([A-Za-z_][A-Za-z0-9_]*)[\'"]\s*\)', i).groups()[0]
        except AttributeError:
            return False

Try it online!

Ruby, 46 bytes

Feels like the dirtiest code I've ever written for Ruby.

Requires that the global variables you call has a unique value that isn't on any other global variable, because the only way to do this challenge in Ruby is to do an search on all global variables and return the first match. OP says it's ok, and is free to judge if my solution is valid.

Note that global variables start with $ in Ruby, for if you want to add extra test case stuff.

->v{global_variables.find{|n|eval(n.to_s)==v}}

Try it online!

R

function(x) if (identical(substitute(x), x)) FALSE else substitute(x)

substitute returns the parse tree for an unevaluated expression. The identical conditional makes sure that this unevaluated expression isn't identical to the expression itself; i.e. that the passed in parameter isn't a literal.

C#

string n<T>(Expression<Func<T>>m) =>
    (m.Body as MemberExpression)?.Member?.Name ?? null;

Full/Formatted version:

using System;
using System.Linq.Expressions;

class P
{
    static void Main()
    {
        var apple = "Hello";
        var nil = "Nothing";
        var SOMETHING = 69;

        Console.WriteLine(n(() => apple));
        Console.WriteLine(n(() => nil));
        Console.WriteLine(n(() => SOMETHING));
        Console.WriteLine(n(() => 3.14159));

        Console.ReadLine();
    }

    static string n<T>(Expression<Func<T>>m)
        => (m.Body as MemberExpression)?.Member?.Name ?? null;
}

Another way to do this is by reflecting on the type like so:

public static string GetParameterName<T>(T item)
{
    var properties = typeof(T).GetProperties();

    return properties.Length > 0 ? properties[0].Name : null;
}

However, you have to call it like:

GetParameterName(new { apple });

It then also fails for 3.14159 by returning Length and for that you also have to call it like the following instead:

GetParameterName(new double[]{ 3.14159 });

In C# 6.0 we also have:

nameof

But this won't compile if you pass it something that isn't a variable e.g. 3.14159. I believe it also evaluates the input at compile time so it seems like it fails that requirement as well.

Perl 5 + Devel::Caller

use 5.010;
use Devel::Caller qw/caller_vars/;
use Scalar::Util qw/refaddr/;

sub v {
   # find all operands used in the call, formatted as variable names
   my @varsused = caller_vars(0,1);
   scalar @varsused == 1 or return; # exactly one operand, or return false
   $varsused[0] =~ s/^\$// or return; # the operand actually is a variable
   # it's possible we were given an expression like "~$test" which has only
   # one operand, but is not a variable in its own right; compare memory
   # addresses to work this out
   refaddr \ ($_[0]) == refaddr \ (${$varsused[0]}) or return;
   return '$' . $varsused[0];
}

# some test code

our $test = 1;
our $test2 = 2;
our $test3 = 3;

say v($test2);
say v(2);
say v(~$test3);
say v($test);
say v($test + 1);
say v(++$test);
say v($test3);

We use Devel::Caller (a debugger-like module) to walk the call stack, looking for the call to the function, and return all the operands within the argument, returning them as variable names. If there's more (or less) than one operand, we weren't called with a variable. If the operand wasn't a variable, it won't have a name and we can detect that too.

The trickiest case is if we get a one-operand expression involving a variable, such as ~$x. We can figure out if this has occurred by taking a reference to the variable directly from the symbol table (using the ${…} symbolic reference syntax) and comparing its memory address to the value we were passed as an argument (which is, conveniently, passed by reference). If they're different, we have an expression rather than a lone variable.

Note that if we call this function with a preincrement or predecrement expression on a single variable, as in v(--$x), we get $x returned. This is because it's actually the variable itself that's being passed to the function in this case; it just gets incremented or decremented beforehand. I hope this doesn't disqualify the answer. (In a way, it makes it better, because it shows that we're checking the argument itself rather than just reading the source code.)

Mathematica

f~SetAttributes~HoldAll;
f[_] = False;
f[x_Symbol?ValueQ] := SymbolName@Unevaluated@x;

Mathematica likes to evaluate everything, so to make it stop, we have to fight against it. In its own language.

How?

f~SetAttributes~HoldAll;

Tells Mathematica that whenever function f is called, its arguments shouldn't be evaluated (i.e. held).


f[_] = False;

When f is called with an argument, output False. (?!)


f[x_Symbol?ValueQ] := SymbolName@Unevaluated@x;

When f is called with a defined Symbol (which has a value), output the symbol name of the input.

The previous line does not take precedence, despite being defined earlier, because this definition is more specific. As the Wolfram Documentation states: Mathematica "tries to put specific definitions before more general definitions."

Mathematica is very stubborn and keeps trying to evaluate variables whenever possible. The extra Unevaluated takes care of that.

MATLAB

varname = @(x) inputname(1);

Within a function there are a few preset variables like varargin or nargin, among those we also have inputname.

stolen from here

Mathematica

f[x_] := ValueQ @ x && ToString @ HoldForm @ x
SetAttributes[f, HoldFirst]

The HoldFirst attribute prevents f from evaluating its argument before invoking the function. ValueQ @ x then checks whether the given argument is a variable that has been given a value. If not we just return False due to short-circuiting. Otherwise, we obtain the variable name with ToString @ HoldForm @ x.