2010-04-08 13 views
21

फ़ंक्शन (या कुछ डीएसएलिश) लिखने का सबसे अच्छा तरीका क्या है जो मुझे रूबी में यह कोड लिखने की अनुमति देगा। मैं function write_pair फ़ंक्शन कैसे बनाऊंगा?रूबी - वेरिएबल नाम प्रिंट करें और उसके मान

username = "tyndall" 
write_pair username 
# where write_pair username outputs 
username: tyndall 

क्या ऐसा करना संभव है? ऐसा करने का सबसे आसान तरीका खोज रहे हैं।

+0

Exemplor केवल ऐसा नहीं कर सकते, लेकिन फिर भी प्रिंट आउट 'list.first: 1'। –

उत्तर

21

ज़रूर यह संभव है

data = {"username" => "tyndall"}

या यहां तक ​​कि,: लेकिन आप कुछ इस तरह कर सकता है!

मेरे समाधान वस्तु # object_id पहचान द्वारा वर का परीक्षण करती है: http://codepad.org/V7TXRxmL
यह बाध्यकारी गुजर शैली में अपंग है ...
हालांकि यह अभी तक सिर्फ स्थानीय वार्स के लिए काम करता है, यह आसानी से बनाया जा जा सकता है "सार्वभौमिक" जोड़ने उपयोग instance_variables आदि जैसे अन्य गुंजाइश-चर-लिस्टिंग तरीकों में से

# the function must be defined in such a place 
# ... so as to "catch" the binding of the vars ... cheesy 
# otherwise we're kinda stuck with the extra param on the caller 
@_binding = binding 
def write_pair(p, b = @_binding) 
    eval(" 
    local_variables.each do |v| 
     if eval(v.to_s + \".object_id\") == " + p.object_id.to_s + " 
     puts v.to_s + ': ' + \"" + p.to_s + "\" 
     end 
    end 
    " , b) 
end 

# if the binding is an issue just do here: 
# write_pair = lambda { |p| write_pair(p, binding) } 

# just some test vars to make sure it works 
username1 = "tyndall" 
username = "tyndall" 
username3 = "tyndall" 

# the result: 
write_pair(username) 
# username: tyndall 
+0

मैं इस बाध्यकारी पर और कहां पढ़ सकता हूं (जिस तरह से आप इस शब्द का उपयोग कर रहे हैं)? यह वह जगह है जहां मैं खो जाता हूं। – BuddyJoe

+0

http://ruby-doc.org/core/classes/Binding.html http://onestepback.org/index.cgi/Tech/Ruby/RubyBindings.rdoc/style/print – clyfe

+9

मुझे गंभीर रूप से चोट पहुंचाने के लिए प्रेरित किया जाएगा कोई भी जो वास्तव में एक परियोजना में इस कोड का उपयोग करेगा। – molf

2

आप वास्तव में रूबी में एक चर का नाम नहीं प्राप्त कर सकते हैं।

username = "tyndall" 
data = {"username", "password", "favorite_color"} 
data.each { |param| 
    value = eval(param) 
    puts "#{param}: #{value}" 
} 
+1

निश्चित रूप से आप कर सकते हैं लेकिन यह मुश्किल है! – clyfe

14

यदि यह आप चर नाम के बजाय एक प्रतीक का उपयोग करने के लिए संभव है, आप कुछ इस तरह कर सकता है:

def wp (s, &b) 
    puts "#{s} = #{eval(s.to_s, b.binding)}" 
end 

उपयोग में:

irb(main):001:0> def wp (s, &b) 
irb(main):002:1> puts "#{s} = #{eval(s.to_s, b.binding)}" 
irb(main):003:1> end 
=> nil 
irb(main):004:0> var = 3 
=> 3 
irb(main):005:0> wp(:var) {} 
var = 3 

ध्यान दें कि आप विधि के लिए खाली ब्लॉक {} गुजरना होगा या इसे बाध्यकारी प्रतीक मूल्यांकन करने के लिए नहीं मिल सकता है। सामान्य मोड में

" Inspect the variable on the current line (in Ruby) 
autocmd FileType ruby nmap ,i ^"oy$Iputs "<esc>A: #{(<esc>"opA).inspect}"<esc> 

चर आप अपने आप में एक लाइन पर निरीक्षण करने के लिए करना चाहते हैं रखो, तो (तब अल्पविराम i) टाइप ,i:

+0

यदि आप .to_s पर कॉल करने जा रहे हैं, तो स्ट्रिंग को सीधे क्यों पास न करें? इस तरह आप अधिक जटिल अभिव्यक्तियों का भी उपयोग कर सकते हैं। इसके अलावा, आप अधिक स्पष्ट b.binding के बजाय b.send (: बाध्यकारी) का उपयोग क्यों करते हैं? (मैं रूबी के लिए नया हूँ)। वैसे भी, यह बहुत अच्छा काम करता है और उस दूसरे समाधान (जिसे write_pair कहा जाता है) से कहीं अधिक सरल है, जिसे मैं – marcus

+0

भी समझ नहीं सकता हूं हां, आप प्रतीक के बजाय स्ट्रिंग (कोई संशोधन आवश्यक नहीं) पास कर सकते हैं, पहली पंक्ति समाधान सिर्फ इस तथ्य को संदर्भित करता है कि आप कुछ 'wp (var) 'टाइप नहीं कर सकते हैं (जैसे प्रश्न में)। पता नहीं/याद रखें कि मैंने स्ट्रिंग के बजाय प्रतीक क्यों चुना, या मैंने '.binding' के बजाय' .send (: बाध्यकारी) 'क्यों रखा - शायद पहले किसी अन्य समाधान के बारे में सोचने और उस से विकसित होने के कारण। =) – Arkku

3

मैं इस के लिए एक vim मैक्रो बना दिया।

foo 
इस में

:: यह इस बदल जाता है

puts "foo: #{(foo).inspect}" 

यह अच्छा है क्योंकि यह किसी भी बाहरी निर्भरता नहीं है (उदाहरण के लिए यदि आप एक पुस्तकालय लोड की है, इसका इस्तेमाल करने की जरूरत नहीं है) है ।

1
def write_pair var, binding 
    puts "#{ var } = #{ eval(var, binding)}" 
end 


username = "tyndall" 
write_pair "username", binding 

यह अजीब लगता है क्योंकि बाध्यकारी कभी परिभाषित नहीं है, लेकिन यह काम करता है। Ruby: getting variable name से:

बाध्यकारी() प्रणाली बाध्यकारी वस्तु जो संदर्भ बिंदु पर विधि बुलाया गया था याद है देता है। फिर आप एक बाध्यकारी eval() में पास करते हैं, और यह उस संदर्भ में चर का मूल्यांकन करता है।

एक स्ट्रिंग पास करने के लिए सुनिश्चित करें, चर नहीं।

1
# make use of dynamic scoping via methods and instance vars 
@_binding = binding 
def eval_debug(expr, binding = @_binding) 
    "#{expr} => #{eval(expr, binding)}" 
end 

# sample invocation: 
x = 10 
puts eval_debug "x" 
puts eval_debug "x**x" 
2

यह एक सरल उपाय है:

def bug string 
    puts '#' * 100 
    puts string + ': ' + eval(string).inspect 
end 

यह इस प्रकार शुरू हो जाती है:

def bug string 
    puts string + eval(string) 
    end 

यह और अधिक पठनीय है

bug "variable" 

आप ले जाने के लिए की जरूरत है आपके साथ वास्तविक चर, आपको टी करना है इसे दो बार दोहराएं, लेकिन फिर आप इसे इनलाइन कर सकते हैं। इस प्रकार:

puts "variable: #{variable}" 
2

बिल्डिंग प्रतीकों से संबंधित & बाइंडिंग ... अगर एक प्रतीक के रूप में चर नाम गुजर आप (जो अतिरिक्त कीस्ट्रोक्स ?! बाहर काटने प्यार नहीं करता है) के लिए काम करता है पिछले उत्तरों के, इस प्रयास करें:

def wp(var_name_as_sym) 
    # gets caller binding, which contains caller's execution environment 
    parent_binding = RubyVM::DebugInspector.open{|i| i.frame_binding(2) } 
    # now puts the symbol as string + the symbol executed as a variable in the caller's binding 
    puts %Q~#{var_name_as_sym.to_s} = #{eval("#{var_name_as_sym.to_s}.inspect", parent_binding)}~ 
end 

aa=1 
bb='some bb string' 
os = OpenStruct.new(z:26, y:25) 

कंसोल आउटपुट:

> wp :aa 
aa = 1 
=> nil 
> wp :bb 
bb = "some bb string" 
=> nil 
> wp :os 
os = #<OpenStruct z=26, y=25> 
=> nil 

का उपयोग माणिक 2.2.2p95

(बुला संदर्भ से getting binding के लिए banister को क्रेडिट)

संबंधित मुद्दे