2009-03-04 12 views
5

किसी रूबी कोड के इस टुकड़े को समझाने कृपया सकते हैं:रूबी कोड समझाया

def add_spec_path_to(args) # :nodoc: 
    args << {} unless Hash === args.last 
    args.last[:spec_path] ||= caller(0)[2] 
end 

मैं संयोजन तार के लिए या किसी अन्य भाषा का बिटवाइज़ ऑपरेटर के रूप में इस्तेमाल << ऑपरेटर देखा है लेकिन किसी को इस संदर्भ में यह समझा जा सकता है। क्या यह किसी भी तरह से एक खाली lamda तर्क पर जोड़ रहा है या मैं पूरी तरह से गलत हूँ?

मैं भी देख सकते हैं इसे इस तरह इस्तेमाल किया:

before_parts(*args) << block 

Hash एक कीवर्ड है?

मुझे यह भी पता नहीं है कि ||= ऑपरेटर क्या कह रहा है।

मैं caller(0)[2] के रूप में अंधेरे में समान रूप से हूं।

उत्तर

11

|| = एक आम रूबी मुहावरे है: यह मान केवल तभी निर्दिष्ट करता है जब यह पहले से सेट न हो। प्रभाव,

if some_variable == nil 
    some_variable = some_value 
end 

या

some_variable= some_value unless some_variable 

===, जब ओवरराइड नहीं की तरह कोड के रूप में ही है पहचान के लिए दो वस्तुओं तुलना करती है। Hash === args.last के मामले में, हैश (जो कि प्रकार क्लास का ऑब्जेक्ट है) यह देखने के लिए जांच कर रहा है कि यह तर्क ऐरे में अंतिम आइटम की कक्षा से मेल खाता है या नहीं। कोड स्पष्ट तथ्य का उपयोग कर रहा है कि कक्षा # === के क्रियान्वयन की तुलना की गई वस्तु के वर्ग पर एक चेक को मजबूर करता है। {}

प्रदान करने के लिए की जरूरत के बिना

a = [{}] 
Hash === a.last #=> true 
a.last === Hash #=> false 

एक पद्धति के लिए पीछे तर्क एक हैश की सामग्री के रूप में आपूर्ति की जा सकती:

यह दूसरी तरह के आसपास काम नहीं करता है, उदाहरण के लिए तो आप यह कर सकते हैं:

def hello(arg1, arg2, arg3) 
    puts [arg1.class, arg2.class, arg3.class].join(',') 
end 

hello 1,2,3 #=> Fixnum,Fixnum,Fixnum 
hello :a, "b", :c => 1, :d => 99 #=> Symbol,String,Hash 

यह अक्सर फ़ंक्शन पर वैकल्पिक पैरामीटर की चर-लंबाई सूची प्रदान करने के लिए उपयोग किया जाता है।

क्या आप वाकई मूल कोड को ठीक से ट्रांसक्रिप्ट कर चुके हैं, btw? तर्कों की एक सरणी प्राप्त करने के लिए, आप आमतौर पर तर्क के रूप में तर्क में एक * जोड़ देंगे, अन्यथा तर्कों को एक सरणी के रूप में इनपुट करना होगा, whcih वस्तु को हराने के बजाय होगा।

def add_spec_path_to(*args)    # now args is an array 
    args << {} unless Hash === args.last # if trailing arguments cannot be 
             # interpreted as a Hash, add an empty 
             # Hash here so that following code will 
             # not fail 
    args.last[:spec_path] ||= caller(0)[2] # Set the spec_path option if it's not 
             # already set 
end 

संपादित करें: * args बात पर आगे विस्तार, इस प्रयास करें:

def x(*args) 
    puts args.join(',') 
    puts args.map{|a| a.class }.join(',') 
end 

x 1,2,:a=>5,:b=>6 
1,2,a5b6 
Fixnum,Fixnum,Hash 

... * args का उपयोग कर का कारण बनता है आर्ग एक सरणी के रूप में विधि के समक्ष प्रस्तुत किया जाना है। मैं *, इस तरह, उदाहरण के लिए उपयोग नहीं करते हैं:

def y(args) 
    puts args.join(',') 
    puts args.map{|a| a.class }.join(',') 
end 

... तो आर्ग इससे पहले कि मैं विधि कॉल, या मैं एक "ArgumentError मिलेगा एक सरणी हो गया है: की गलत संख्या तर्क "कुछ भी के लिए लेकिन एक चीज बीत गई। तो यह इस तरह दिखना चाहिए:

y [1,2,{:c=>3,:d=>4}] 

... स्पष्ट रूप से के साथ बनाया हैश {} के साथ। और यह बदसूरत है।

उपर्युक्त सभी एमआरआई 1.8.6, बीटीडब्ल्यू के साथ परीक्षण किया गया।

+0

नहीं, किसी सरणी में गुजर समझ में आता है, के बाद से आर्ग वापस नहीं है, इसलिए अन्यथा, एक साथ जोड़ दिया हैश खो जाएगा। – rampion

+0

मुझे यकीन नहीं है कि मैं समझता हूं: आप इस तरह की विधि को कॉल करेंगे: some_method ([arg1, arg2, arg3], options_hash)? यह डरावना है: ऊपर संपादित उत्तर देखें ... –

+0

ग्रेट स्पष्टीकरण, माइक। –

14

मुझे लगता है कि args एक Array है।

Hash एक क्लास का नाम है - पहली पंक्ति पर argsजब तकargs के अंतिम तत्व पहले से ही एक Hash (=== कक्षाएं परीक्षण के लिए ऑपरेटर एक वस्तु एक निश्चित वर्ग के है या नहीं) है एक खाली हैश {} धक्का ।

||= ऑपरेटर += ऑपरेटर के समान है: इसे और अधिक या कम करने के लिए बराबर है:

args.last[:spec_path] = args.last[:spec_path] || caller(0)[2] 

इसलिए, यह args.last[:spec_path] सेट हो जाएगा यदि और केवल यदि यह वर्तमान में सेट नहीं की जाती।

caller विधि कॉलिंग विधि के बारे में जानकारी देता है।

1

में थोड़ा छोटा तरह:

def add_spec_path_to(args) # :nodoc: 

... 

# Append an empty hash to args UNLESS the last arg is a hash.. in which case do nothing 
args << {} unless Hash === args.last # so we need a hash. If it is not there, make an empty one and put it there. 

... 

#if args.last[:spec_path] equals nil or false, set it to caller(0)[2]... 

#so inside that hash from the first part, if :spec_path is not there, create it by using caller(0)[2]. 

args.last[:spec_path] ||= caller(0)[2] 

... 

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