একটি ভেরিয়েবলের নাম মুদ্রণ করুন [বন্ধ]


20

একটি ফাংশন লিখুন (একটি সম্পূর্ণ প্রোগ্রাম নয়), যাতে যদি ফাংশনটিকে একটি একক বিশ্বব্যাপী ভেরিয়েবল (বা আপনার ভাষার নিকটতম সমতুল্য) হিসাবে যুক্তি হিসাবে ডাকা হয়, তবে এটি সেই পরিবর্তনশীলটির নাম আউটপুট করে (অর্থাত্ মুদ্রণ বা প্রত্যাবর্তন করে)। যদি আর্গুমেন্টটি পরিবর্তনশীল না হয় তবে পরিবর্তে একটি মিথ্যা মান আউটপুট করুন। (আপনার পক্ষে মামলাটি পরিচালনা করতে হবে না যেখানে আর্গুমেন্টটি পরিবর্তনশীল, তবে বৈশ্বিক নয়))

ফাংশন কল এবং ফাংশন সংজ্ঞায়নের মধ্যে একটি সংকলন-সময় সংযোগ থাকা উচিত নয় (উল্লেখযোগ্যভাবে, ফাংশন সংজ্ঞাটি কোনও ম্যাক্রো বা অনুরূপ কনস্ট্রাক্ট হতে পারে না যা উত্স কোডের আক্ষরিক খণ্ড আকারে আর্গুমেন্ট গ্রহণ করে, না পাঠ্যে বা বিমূর্ত সিনট্যাক্স ট্রিতে গঠন)। এটি হল: যে ভাষাগুলিতে পৃথক সংকলন সমর্থন করে, ফাংশন কলটি প্রথমে সংকলন করা থাকলেও (ফাংশন সংজ্ঞা সম্পর্কে কোনও জ্ঞান না থাকলেও সম্ভবত কোনও ধরণের স্বাক্ষর বা সমতুল্য) প্রোগ্রামটি অবশ্যই কাজ করা উচিত, তারপরে ফাংশন সংজ্ঞাটি সংকলিত হয়। যদি ভাষার পৃথক সংকলন না থাকে তবে আপনার অবশ্যই কল এবং সংজ্ঞাটির মধ্যে একই ধরণের বিচ্ছিন্নতার লক্ষ্য রাখতে হবে।

একটি সংকলিত ভাষা ব্যবহার করে, আপনি ডিস্ক থেকে সম্পূর্ণ প্রোগ্রামের সংকলিত ফর্মটি পড়তে পারেন, এবং ধরে নিতে পারেন যে প্রোগ্রামটি ডিবাগের তথ্য দিয়ে সংকলিত হয়েছিল। (এইভাবে, কোনও প্রোগ্রাম থেকে নিজেই কোনও ডিবাগার সংযুক্ত করে কাজ করা সমাধানগুলি অনুমোদিত))

মনে রাখবেন যে প্রতিটি ভাষায় এই কাজটি সম্ভব নাও হতে পারে।

উদাহরণ:

var apple = "Hello"
p(apple) // apple

var nil = "Nothing"
p(nil) // nil

var SOMETHING = 69
p(SOMETHING) // SOMETHING

function foo(){}
p(foo) // foo

p(3.14159) // false

p(function foo(){}) // false

মন্তব্যগুলি বর্ধিত আলোচনার জন্য নয়; এই কথোপকথন চ্যাটে সরানো হয়েছে ।
ডেনিস

উত্তর:


31

জাভা

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;
}

এটি বর্তমানে কয়েকটি গোছা নিয়ে কাজ করে:

  1. এটি সংকলনের জন্য আপনি যদি কোনও আইডিই ব্যবহার করেন তবে এটি অ্যাডমিন হিসাবে চালিত না করা (অস্থায়ী শ্রেণীর ফাইলগুলি কোথায় সংরক্ষণ করা হয়েছে তার উপর নির্ভর করে) এটি কাজ করতে পারে না
  2. ব্যবহার করে আপনি কম্পাইল করতে হবে javacসঙ্গে -gপতাকা। এটি সংকলিত শ্রেণীর ফাইলের স্থানীয় ভেরিয়েবলের নাম সহ সমস্ত ডিবাগিং তথ্য উত্পন্ন করে।
  3. এটি একটি অভ্যন্তরীণ জাভা এপিআই ব্যবহার করে com.sun.tools.javapযা শ্রেণিবদ্ধের বাইটকোডকে পার্স করে এবং একটি মানব পাঠযোগ্য ফলাফল উত্পাদন করে। এই এপিআইটি কেবল জেডিকে গ্রন্থাগারগুলিতে অ্যাক্সেসযোগ্য তাই আপনাকে জেডিকে জাভা রানটাইম ব্যবহার করতে হবে বা আপনার ক্লাসপাথে টুলস.জার যুক্ত করতে হবে।

প্রোগ্রামটিতে পদ্ধতিটি একাধিকবার বলা হলেও এটি এখন কাজ করা উচিত। দুর্ভাগ্যক্রমে এটি এখনও কাজ করে না যদি আপনার একক লাইনে একাধিক অনুরোধ থাকে। (যা করে তার জন্য, নীচে দেখুন)

এটি অনলাইন চেষ্টা করুন!


ব্যাখ্যা

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";

এই বিভাগে আমরা কোন শ্রেণিতে রয়েছি এবং ফাংশনটির নামটি সম্পর্কে কিছু সাধারণ তথ্য পাওয়া যায়। এটি একটি ব্যতিক্রম তৈরি করে এবং স্ট্যাক ট্রেসের প্রথম 2 টি এন্ট্রি বিশ্লেষণ করে সম্পন্ন হয়।

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

প্রথম এন্ট্রিটি হ'ল রেখাটি যে ব্যতিক্রমটি নিক্ষেপ করা হয় যার উপরে আমরা পদ্ধতি নামটি ধরে ফেলতে পারি এবং দ্বিতীয় প্রবেশটি যেখানে ফাংশনটি ডেকে আনা হয়েছিল।

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;

অবশেষে আমরা স্থানীয় পরিবর্তনশীল সারণীতে লাইনটি থেকে ভেরিয়েবলের নাম পার্স করি। যদি এটি না পাওয়া যায় তবে শূন্যস্থানটি ফিরুন যদিও আমি এরকম হওয়ার কোনও কারণ দেখিনি।

সবগুলোকে একত্রে রাখ

 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;

এটি মূলত আমরা যা দেখছি। উদাহরণ কোডে প্রথম অনুরোধটি লাইন 17 line লাইননিবারটবেলে লাইন 17 দেখায় যে সেই লাইনের শুরুটি বাইটকোড লাইন সূচক 18 index এটি System.outলোড। তারপরে আমাদের কাছে aload_2পদ্ধতি কলের ঠিক আগে উপস্থিত রয়েছে তাই আমরা লোকাল ভারিটেবল টেবিলের স্লট 2 তে পরিবর্তনশীলটি সন্ধান করি যা strএই ক্ষেত্রে রয়েছে।


মজাদার জন্য, এখানে একটি যা একই লাইনে একাধিক ফাংশন কল পরিচালনা করে। এর ফলে ফাংশনটি আদর্শবান হতে না পারে তবে এ জাতীয় বিন্দু। এটি অনলাইন চেষ্টা করুন!


1
এই উত্তরটি ভালবাসি। একই লাইন বরাবর কিছু চিন্তা ছিল। এক নোট যদিও, যদি আপনি প্রোগ্রামের একই লাইনে একাধিক কল অন্তর্ভুক্ত, তাহলে এটি নির্ধারণ করতে পারি না যা এক পদ্ধতি কল করছে (নিশ্চিত না এই আপনার বর্তমান পদ্ধতির সংশোধন করা যেতে পারে) যে, উদাহরণস্বরূপ, চলন্ত চেষ্টা System.out.println(e.getParamName(str));System.out.println(e.getParamName(str2));System.out.println(e.getParamName(str4));সম্মুখের টিআইও লিঙ্কের একটি লাইন।
পুনপুন 1000

আপনি উদ্ধার করতে পারেন javapএই মত অবস্থান: Paths.get(System.getProperty("java.home"), "bin", "javap")
অলিভিয়ার গ্রাগোয়ার

@ অলিভিয়ারগ্রোগোয়ার ধন্যবাদ তবে আমি অভ্যন্তরীণ জাভা এপি দিয়ে জাভাটি চালু করতে চলেছি যাতে আমার আর কোডে ডিস্কের সঠিক অবস্থান পাওয়ার প্রয়োজন নেই (কেবল শ্রেণিপথ)
পোকে

@ পুনপুন1000 হ্যাঁ আমি নিশ্চিত নই যে আদর্শবান্ধব ক্রিয়াকলাপ বজায় রাখার সময় এটি ঠিক করার কোনও ভাল উপায় আছে কিনা তবে আমি এমন কিছু সংশ্লেষ করতে পারি যা কেবল মজাদার জন্য ফাংশনের বাইরে রাষ্ট্র ব্যবহার করে।
পোকে

1
@ PunPun1000 এমন একটি সংস্করণ যুক্ত করেছে যা এক লাইনে একাধিক কল পরিচালনা করতে পারে। এটি কেবলমাত্র ফাংশনটির চেয়ে বেশি তাই আমি উত্তর আপডেট করার পরিবর্তে আর একটি ট্রাইআইটঅনলাইন লিঙ্ক যুক্ত করেছি।
পোকে

14

পাইথন 2

এটি আমি লিখেছি সবচেয়ে নোংরা কোড সম্পর্কে কিন্তু এটি কার্যকর। ¯ \ _ (ツ) _ / a অস্তিত্বহীন ভেরিয়েবলের উপর একটি ত্রুটি ফেলে কারণ পাইথন তত্ক্ষণাত আপনাকে তার সাথে ফাংশনটি কল করার জন্য অপছন্দ করবে। নন-ভেরিয়েবলগুলিতে ত্রুটিও ফেলে দেয় তবে এটি চেষ্টা করে / ঠিক করা ছাড়া সমাধান করা যায়।

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]

এটি অনলাইন চেষ্টা করুন!

যদি আমাদের যুক্তিটিকে স্ট্রিং হিসাবে গ্রহণ করার অনুমতি দেওয়া হয় তবে এটি একটি অবৈধ ইনপুটটিতে মিথ্যা মান আউটপুট করার প্রয়োজনীয়তা পূরণ করে।

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

এটি অনলাইন চেষ্টা করুন!


আপনি প্রায় একই উত্তর পোস্ট করেছিলেন, যখন আমি আমার কাছে ব্যাখ্যা
ডেড পসুম

1
@ ডেডপসাম সর্বদা পোস্ট করুন এবং উত্তর দিন এবং একটি সম্পাদনা হিসাবে পরে একটি ব্যাখ্যা যুক্ত করুন। ;)
অর্জুন

8
পি: @Arjun, ওহ মহান তাই আমরা EditGolf সেইসাথে CodeGolf খেলা আছে
Wossname

12

ম্যাথামেটিকাল

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

HoldFirstঅ্যাট্রিবিউট বাধা দেয় fফাংশন invoking আগে তার যুক্তি মূল্যায়নের থেকে। ValueQ @ xতারপরে প্রদত্ত আর্গুমেন্টটি একটি ভেরিয়েবল যা মান দেওয়া হয়েছে তা পরীক্ষা করে। না হলে আমরা কেবল Falseশর্ট সার্কিটের কারণে ফিরে আসি। অন্যথায়, আমরা এর সাথে চলক নামটি পাই ToString @ HoldForm @ x


ডাং, ম্যাথমেটিকাকে কীভাবে পরিচালনা করে তা গালাগালি করে And... আমি পছন্দ করি যে কীভাবে সঠিক যুক্তিটি Andবুলিয়ান এক্সপ্রেশন হতে পারে না।
জংহওয়ান মিন

আমি জানি এটি কোড গল্ফ নয়, তবে কেন কেন f[x_] := ValueQ @ x && HoldForm @ x? যদি ইনপুটটি ভেরিয়েবল হয় কিনা তা HoldFormখতিয়ে দেখার প্রয়োজনীয়তা না থাকলে নিজের কাজ করে।
নেজিনিসিস

HoldAllএর বদলে HoldFirst?
গ্রেগ মার্টিন

1
@ngenisis কারণ এটি ফিরে আসে HoldForm[a]এবং না "a"। গাণিতিক নোটবুকে এগুলি একই প্রদর্শিত হয়, ফাংশনটি সীমানা থেকে স্বতন্ত্রভাবে বিদ্যমান, তাই আমি একটি সমাধান চাই যা একটি স্ট্রিং ফেরত দেয়।
মার্টিন ইন্ডার

1
হোয়াইটস্পেস অপসারণের জন্য অনুরোধ কারণ ... ওম ... কারণ
ক্যালকুলেটরফলাইন

7

ম্যাথামেটিকাল

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

গাণিতিক সকল কিছুর মূল্যায়ন করতে পছন্দ করে , তাই এটি বন্ধ করতে আমাদের এর বিরুদ্ধে লড়াই করতে হবে। নিজস্ব ভাষায়।

কিভাবে?

f~SetAttributes~HoldAll;

ম্যাথমেটিকাকে বলে যে যখনই ফাংশন fবলা হয়, এর যুক্তিগুলি মূল্যায়ন করা উচিত নয় (অর্থাত্ অনুষ্ঠিত)।


f[_] = False;

যখন fআর্গুমেন্ট, আউটপুট দিয়ে ডাকা হয় False। (?!)


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

যখন fসংজ্ঞায়িত প্রতীক (যার একটি মান থাকে) দিয়ে ডাকা হয়, তখন ইনপুটটির প্রতীক নামটি আউটপুট দিন।

পূর্ববর্তী লাইনটি পূর্বনির্ধারিত হওয়া সত্ত্বেও অগ্রাধিকার গ্রহণ করে না, কারণ এই সংজ্ঞাটি আরও সুনির্দিষ্ট। ওল্ফ্রাম ডকুমেন্টেশন যেমন বলে: ম্যাথমেটিকা ​​"আরও সাধারণ সংজ্ঞা দেওয়ার আগে নির্দিষ্ট সংজ্ঞা রাখার চেষ্টা করে।"

গণিত খুব জেদী এবং যখনই সম্ভব ভেরিয়েবলগুলি মূল্যায়নের চেষ্টা করে। অতিরিক্ত Unevaluatedযে যত্ন নেয়।


7

সি শার্প

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

সম্পূর্ণ / ফর্ম্যাট সংস্করণ:

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;
}

এটি করার আরেকটি উপায় হ'ল এর ধরণের প্রতিবিম্বিত করে:

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

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

যাইহোক, আপনি এটি কল করতে হবে:

GetParameterName(new { apple });

এটি 3.14159ফিরে আসার পরেও ব্যর্থ হয় Lengthএবং এর জন্য আপনাকে নীচের মত এটি কল করতে হবে:

GetParameterName(new double[]{ 3.14159 });

সি # 6.0 এও আমাদের রয়েছে:

nameof

তবে এটি সংকলন করে না আপনি যদি এমন কিছু পাস করেন যা ভেরিয়েবল যেমন না 3.14159। আমি বিশ্বাস করি এটি সংকলনের সময় ইনপুটটিও মূল্যায়ন করে তাই দেখে মনে হয় এটি প্রয়োজনীয়তাও ব্যর্থ হয়।


এটি কিছুক্ষণ চতুর কারণ ল্যামডা কাপড় একেবারে অপরিহার্য (ie আপনি শুধু পরিবর্তনশীল মধ্যে পাস করতে পারবে না, আপনি কিছু যে কম্পাইল একটি হওয়া উচিত চিনতে পারবে পাস করতে হবে হচ্ছে ... Expression)। আপনারও গণনা করা উচিত using System.Linq.Expressions;
ভিজ্যুমেলন

যদিও এই "বিমূর্ত সিনট্যাক্স ট্রি ফর্ম মধ্যে যুক্তি গ্রহণ" হিসাবে গণনা করা হয়?
ম্যাটি ভির্ককুনেন

@ ভিজুয়ালমেলন আমি সি # তে এটি করার জন্য অন্য কোনও উপায় খুঁজে পাইনি তাই আমি এটি এইভাবে করেছি did এছাড়াও এটি কোড-গল্ফ নয় তাই এটি কোনও বিষয় নয়,
TheLethalCoder

... দুঃখিত, বুঝতে পারি না যে এখানে কোনও বাইট গণনা নেই!
ভিজ্যুমেলন

6

ম্যাটল্যাব

varname = @(x) inputname(1);

একটি ফাংশনের মধ্যে কয়েকটি প্রিসেট ভেরিয়েবলগুলি রয়েছে varargin বা এর narginমধ্যে রয়েছে আমাদের মধ্যে inputname

এখান থেকে চুরি


আমি জানতাম না যে এর অস্তিত্ব আছে। আমি এটির সাথে কিছুটা x=42;y=54; f=@(x)eval(inputname(1));f(x),f(y)
খেলাম

হাহাহা, eval==evil= ডি (এটি আসলে সাথে কাজ করে x=42;y=54; f=@(x)eval('inputname(1)');f(x),f(y))
flawr

হ্যাঁ, এটি ঠিক যে কোনও অনামী ফাংশনটি কোনও ওয়ার্কস্পেস ভেরিয়েবল সম্পর্কে জানে না, সুতরাং onlyভাল কেবল মূল্যায়ন করতে পারে xএবং তারপরে evalকর্মক্ষেত্রের ভেরিয়েবলটি নয়, তবে ফাংশনটির যুক্তিটি তৈরি করে।
সানাইজাইজ

6

আর

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

substituteঅমূল্য অভিব্যক্তির জন্য পার্স গাছ প্রদান করে। identicalশর্তাধীন তোলে নিশ্চিত যে এই unevaluated অভিব্যক্তি অভিব্যক্তি নিজেই অভিন্ন নয়; অর্থাত প্যারামিটারে পাস হওয়া আক্ষরিক নয়।


4

পাইথন 2

কিছু গবেষণা হয়েছে। অজগরটিতে এটি সম্ভব হবে বলে মনে হয় তবে আমি এখনও কিছু ঝামেলা খুঁজে পাওয়ার আশা করি।
সমাধানটি নিখুঁত নয়, কারণ এটি কোডের কিছু কাঠামো ধরে নেয়। তবুও আমি এখনও তা ভাঙ্গি নি।

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()

এটি চারপাশের সুযোগগুলি দেখার জন্য এবং কোথায় ফাংশন get_nameডাকা হয়েছে তা সন্ধান করতে পরিদর্শন ব্যবহার করে । উদাহরণস্বরূপ inspect...[1]ফিরে আসবে

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

এবং inspect...[1][4]কোড সহ আমাদের তালিকা প্রদর্শন করবে, যেখানে ফাংশন বলা হয়:

['print get_name( a )\n']

এরপরে আমি যুক্তির নামটি পুনরুদ্ধার করতে regex ব্যবহার করেছি

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

এবং .lstrip().rstrip()ব্রেসেটে রাখা হতে পারে এমন সমস্ত সাদা স্থান সরিয়ে ফেলতে।

কিছু জটিল ইনপুট সহ উদাহরণ



4

পিএইচপি

গ্লোবাল ভেরিয়েবলের অ্যারেতে ভেরিয়েবলের মানটি অনন্য Ne

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

এটি অনলাইন চেষ্টা করুন!

পিএইচপি , 96 বাইট

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

এটি অনলাইন চেষ্টা করুন!

প্রয়োজন হয় যে ভেরিয়েবলটি সরাসরি ফাংশন কলে শুরু করা হয়।

শেষ বিশ্বব্যাপী চলক সমান আত্মসমর্পণ পরিবর্তনশীল কিনা তা পরীক্ষা করে


এটি কোড গল্ফ নয়।
Okx

@ ওকএক্স আমি জানি এই মুহুর্তে আমার আর কোনও ভালো ধারণা নেই।
জার্গ হালসারম্যান


4

জাভাস্ক্রিপ্ট (ES6)

window( Object.getOwnPropertyNames(w)) এর সমস্ত সম্পত্তির নামের জন্য, সেই সম্পত্তির জন্য প্রাপ্তির সংজ্ঞা দেওয়ার চেষ্টা করুন যা সম্পত্তির নাম দেয়।

তারপরে, কোনও মানচিত্রে একটি এন্ট্রি যুক্ত করুন Mযেখানে মূলটি সম্পত্তিটির (সম্ভবত ওভাররাইড করা) মান এবং মানটি সম্পত্তিটির নাম।

ফাংশনটি fকেবল একটি পরিবর্তনশীল (যেমন একটি সম্পত্তি window) নেয় এবং Mসেই মানটির জন্য এন্ট্রি ফিরিয়ে দেয় ।

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)

এটি windowনিজেকে ব্যতীত সমস্ত অন্তর্নির্মিত গ্লোবাল ভেরিয়েবলের জন্য কাজ করে, কারণ এটির সাথে আলাদা করার কোনও উপায় নেই top(ফ্রেমে চালিত না হওয়া পর্যন্ত ):

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

কিছু কারণে, আমি একটি ত্রুটি পেয়ে করছি: L not a function। কেন যে হবে?
কালেব ক্লেভেটার

কি দারুন! এটি ES6 এর চেয়ে গভীর যা আমি কিছুক্ষণ দেখেছি।
এমডি এক্সএফ

পুনঃটুইট আমি দ্বিতীয় লাইনে একটি কমা ভুলে গেছি। এটি সমস্যাযুক্ত হতে পারে বা নাও হতে পারে।
darrylyeo

3

পার্ল 5 + ডিভেল :: কলার

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);

আমরা কল স্ট্যাকটি হাঁটার জন্য কলটি (একটি ডিবাগার-জাতীয় মডিউল) ব্যবহার করি, ফাংশনে কলটি সন্ধান করে এবং সমস্ত ক্রিয়াকলাপকে আর্গুমেন্টের মধ্যে ফিরিয়ে আনা, এগুলি পরিবর্তনশীল নাম হিসাবে ফিরিয়ে আনি। যদি একের তুলনায় আরও বেশি (বা তার চেয়ে কম) থাকে তবে আমাদের একটি ভেরিয়েবলের সাথে ডাকা হত না। অপারেন্ড যদি কোনও পরিবর্তনশীল না হয় তবে এর কোনও নাম থাকবে না এবং আমরা এটিও সনাক্ত করতে পারি।

সবচেয়ে জটিল ক্ষেত্রে হ'ল যদি আমরা কোনও ভেরিয়েবলের সাথে জড়িত ওয়ান-অপারেণ্ড এক্সপ্রেশন পাই তবে ~$x। আমরা প্রতীক টেবিল ( ${…}প্রতীকী রেফারেন্স সিনট্যাক্স ব্যবহার করে ) থেকে ভেরিয়েবলের কোনও রেফারেন্স গ্রহণ করে এবং এর স্মৃতি ঠিকানাটির সাথে তুলনা করে আমাদেরকে একটি আর্গুমেন্ট হিসাবে (যা স্বাচ্ছন্দ্যে, রেফারেন্স দিয়ে পাস করা হয়েছে) তুলনা করে এটি নির্ধারণ করতে পারি )। যদি সেগুলি আলাদা হয় তবে আমাদের একাকী পরিবর্তনশীল না হয়ে অভিব্যক্তি থাকে।

মনে রাখবেন যদি আমরা, একটি preincrement বা একটি একক পরিবর্তনশীল উপর predecrement অভিব্যক্তি সঙ্গে এই ফাংশন কল হিসেবে v(--$x), আমরা পেতে $xফিরিয়ে দিয়েছে। এর কারণ এটি আসলে ভেরিয়েবল নিজেই যা এই ক্ষেত্রে ফাংশনে দেওয়া হচ্ছে; এটি কেবল বর্ধিত বা পূর্বে হ্রাস পেয়েছে। আমি আশা করি এটি উত্তরটিকে অযোগ্য ঘোষণা করবে না। (একটি উপায়ে এটি এটি আরও ভাল করে তোলে, কারণ এটি দেখায় যে আমরা উত্স কোডটি পড়ার চেয়ে যুক্তিটি নিজেই যাচাই করছি))


3

পিএইচপি

অন্য পিএইচপি জমা দেওয়ার ক্ষেত্রে কেবল যদি পরীক্ষা দেওয়া হয় যে প্রদত্ত মান কোনও গ্লোবালের মানের সাথে মেলে তবে এই সংস্করণটি মানটির সাথে একটি রেফারেন্স নিয়ে কাজ করে:

// 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";
}

গ্লোবাল ভেরিয়েবল কল করার সময় অন্য মানের একটি রেফারেন্স হলেও এটি এখন কাজ করা উচিত।

এটি এখানে পরীক্ষা করুন


শেখার প্রচেষ্টার জন্য দুর্দান্ত এবং আপনাকে অনেক ধন্যবাদ
Jurg Hülsermann

@ জার্গএলসারম্যান এমনকি এটির উন্নতি করার একটি উপায় খুঁজে পেয়েছে!
ক্রিস্টোফ

3

Roda

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

এটি অনলাইন চেষ্টা করুন!

এর জন্য রাদার একটি বিল্টিন ফাংশন রয়েছে - name। দুর্ভাগ্যক্রমে, যদিও, ভেরিয়েবলটি দেওয়া না হলে এটি মিথ্যা মান দেয় না।

এই কোড রেফারেন্স শব্দার্থবিজ্ঞানের বিভিন্ন বৈশিষ্ট্য আপত্তিজনক। লাইন দ্বারা ব্যাখ্যা লাইন:

f(&a...) {

ফাংশনটি রেফারেন্স আর্গুমেন্টগুলির একটি পরিবর্তনশীল সংখ্যা নেয় ( &a...)। উল্লেখের তালিকা তৈরির জন্য এটিই রাডায় একমাত্র উপায়।

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

দ্বিতীয় লাইনে এর উপাদানগুলিকে aস্ট্রিমে চাপানো হয় ( a())। এই উপাদানগুলি উল্লেখ করা হয় যদি ফাংশনটি পরিবর্তনশীল এবং সাধারণ মানগুলি অন্যথায় দেওয়া হত।

উপাদানগুলি আন্ডারস্কোর লুপ ব্যবহার করে পুনরাবৃত্তি হয়। আন্ডারস্কোর সিনট্যাক্স জন্য সিনট্যাক্স চিনি হয় for, লুপ, যাতে name(_)সমতূল্য name(var) for varforলুপে ব্যবহৃত ভেরিয়েবলের নাম ফর্মের <sfvN>যেখানে এন পরিবর্তিত হয়। (অর্থাত্ " name(<sfv1>) for <sfv1>") কোনও ব্যবহারকারী-সংজ্ঞায়িত ভেরিয়েবলটি রাখা <বা এটি অবৈধ >so

name()ফাংশন দেওয়া ভেরিয়েবলের নাম ফেরৎ। aপুনরাবৃত্ত হওয়ার উপাদানটি যদি কোনও রেফারেন্স হয় তবে তা প্রদত্ত পরিবর্তনশীল name। অন্যথায়, যদি উপাদানটি একটি সাধারণ মান ছিল তবে প্রদত্ত nameভেরিয়েবলটি আন্ডারস্কোর ভেরিয়েবল <sfvN>। এটি রাডায় রেফারেন্সের শব্দার্থবিজ্ঞানের কারণে ঘটে: যদি কোনও ফাংশন একটি রেফারেন্স গ্রহণ করে এবং ফাংশনটি একটি রেফারেন্স ভেরিয়েবল পাস করা হয় তবে পাস হওয়া মানটি রেফারেন্স ভেরিয়েবলের দিকে নির্দেশ করে না তবে রেফারেন্স ভেরিয়েবলের সাথে পরিবর্তিত হয়।

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

তৃতীয় লাইনে আমরা পরীক্ষা করি যে প্রবাহের পরিবর্তনশীল নামটিতে একটি <অক্ষর রয়েছে । যদি তা হয় তবে এটি একটি আন্ডারস্কোর ভেরিয়েবল এবং এতে পাস মানটি fকোনও রেফারেন্স ছিল না। অন্যথায় আমরা রেফারেন্সের নাম আউটপুট করি।

ফাংশনে প্রদত্ত ভেরিয়েবলটি একটি রেফারেন্স বা আন্ডারস্কোর ভেরিয়েবল হলে এই সমাধানটি কাজ করে না। তবে, প্রশ্নটি নির্দিষ্ট করে যে কেবলমাত্র বৈশ্বিক চলকগুলি হ্যান্ডেল করা উচিত এবং সেগুলি রেডায় রেফারেন্স বা আন্ডারস্কোর ভেরিয়েবল হতে পারে না।


1

রুবি , 46 বাইট

আমি কখনও রুবির পক্ষে লিখেছি এমন ডাইরিস্ট কোডটির মতো মনে হয়।

আপনি যে গ্লোবাল ভেরিয়েবলগুলি কল করেছেন তার একটি অনন্য মূল্য থাকতে হবে যা অন্য কোনও বৈশ্বিক চলকের ক্ষেত্রে নয়, কারণ রুবিতে এই চ্যালেঞ্জটি করার একমাত্র উপায় হ'ল সমস্ত বৈশ্বিক ভেরিয়েবলের অনুসন্ধান করা এবং প্রথম ম্যাচটি ফিরে আসা। ওপি বলেছেন যে এটি ঠিক আছে, এবং আমার সমাধানটি বৈধ কিনা তা বিচারে নির্দ্বিধায়।

নোট করুন যে গ্লোবাল ভেরিয়েবলগুলি $রুবিতে শুরু হয় , যদি আপনি অতিরিক্ত পরীক্ষার কেস স্টাফ যুক্ত করতে চান তবে।

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

এটি অনলাইন চেষ্টা করুন!


1

পিএইচপি

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

মানটি পাওয়া গেলে, ভেরিয়েবলের নাম মুদ্রণ করুন এবং প্রস্থান করুন। কিছুই মুদ্রণ করুন এবং অন্য কোথাও প্রস্থান করুন।

ভেরিয়েবলের নামটি ফিরিয়ে আনতে 61 বাইট বা NULL:

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

এটি নামযুক্ত ফাংশনগুলি খুঁজে পাবে না, কেবলমাত্র ভেরিয়েবলগুলিতে নির্ধারিত।
এবং একটি পিএইচপি ফাংশনটি সনাক্ত করতে পারে না যে কোনও পরামিতি রেফারেন্স বা মান দ্বারা সরবরাহ করা হয়েছিল। ফাংশনটি কেবলমাত্র প্রথম নামটি ফিরিয়ে দেবে যেখানে মানটি ফাংশন প্যারামিটার মানের সাথে মেলে।

এটি অনলাইনে পরীক্ষা করুন


1

শক্তির উৎস

নতুন সংস্করণ তবে পাওয়ারশেল 3.0 থেকে শুরু করে কাজ করে

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

এটি অনলাইন চেষ্টা করুন!

পূর্ববর্তী সংস্করণ

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

এটি অনলাইন চেষ্টা করুন!



0

জাভাস্ক্রিপ্ট (ES6)

ফাংশনে পাস করা ভেরিয়েবলের মানটি সেই পরিবর্তনশীলটির কাছে অনন্য Requ ফেরত পাঠায় undefinedযদি একটি পরিবর্তনশীল পাস করা হয় নি।

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

চেষ্টা করে দেখুন

কোনও কারণে, "আক্ষরিক" পাস করার পরে এটি স্নিপেটে ক্রস-অরিজিন ত্রুটি ছুঁড়ে দেয়।

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))


ব্যাখ্যা

গ্লোবাল অবজেক্টের সমস্ত এন্ট্রি ( this) এ লুপ করুন , প্রতিটি একের মানটি কার্যকরীভাবে প্রদত্ত আর্গুমেন্টের মানের সমান কিনা তা পরীক্ষা করে। যদি কোনও মিলে যাওয়া এন্ট্রি পাওয়া যায় তবে এর কী (নাম) ফাংশন থেকে বেরিয়ে আসে returned


বিকল্প

উপরের মতো একই প্রয়োজনীয়তা সহ

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

2
আমি মনে করি যদি দুটি গ্লোবালের একই মান থাকে তবে এটি ব্যর্থ হয়।
মার্টিন ইন্ডার


@MartinEnder; হ্যাঁ, এটি ধরে নিয়েছে যে পাস করা ভেরিয়েবলের জন্য নির্ধারিত মানটি সেই ভেরিয়েবলের কাছে স্বতন্ত্র; আমি পোস্ট করার সময় এটি অন্তর্ভুক্ত করতে ভুলে গেছি।
শেগি

@CalebKleveter; এর মধ্যে কয়েকটি এই পরিবর্তনের কারণে যে আপনি যে ভেরিয়েবলটির মানটি পার করছেন তার মান সেই ভেরিয়েবলের সাথে অনন্য নয় এবং এর কিছুটি অবৈধ ভেরিয়েবলের নামগুলির কারণে (যেমন, hello--)। এছাড়াও, আপনার varপরিবর্তে ব্যবহার করা দরকার let
শেগি

1
@CalebKleveter দেখুন এখানে মধ্যবর্তী scoping পার্থক্য আরো তথ্যের জন্য letএবং var। আপনার দ্বিতীয় প্রশ্নের কাছে: এটি ঘটেছে কারণ IN_GLOBAL_SCOPEআপনার বৈশ্বিক ক্ষেত্রের মধ্যে একটি ভেরিয়েবল রয়েছে এবং এর মান রয়েছে 1। উপরের পরীক্ষার আগে আপনি এটি চালিয়ে আপনার বৈশ্বিক সুযোগ এবং তাদের মানগুলিতে বিদ্যমান ভেরিয়েবলগুলি পরীক্ষা করতে পারেন:for(x in this)console.log(x+": "+this[x])
শেজি

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.