रूबी में नल विधि का लाभ


116

मैं सिर्फ एक ब्लॉग लेख पढ़ रहा था और देखा कि लेखक ने इस्तेमाल किया tap कुछ इस तरह :

user = User.new.tap do |u|
  u.username = "foobar"
  u.save!
end

मेरा सवाल यह है कि वास्तव में उपयोग करने का लाभ या लाभ क्या है tap? क्या मैं ऐसा नहीं कर सकता:

user = User.new
user.username = "foobar"
user.save!

या बेहतर अभी तक:

user = User.create! username: "foobar"

जवाबों:


103

जब पाठकों का सामना होता है:

user = User.new
user.username = "foobar"
user.save!

उन्हें सभी तीन पंक्तियों का पालन करना होगा और फिर यह पहचानना होगा कि यह केवल नाम का एक उदाहरण बना रहा है user

अगर यह थे:

user = User.new.tap do |u|
  u.username = "foobar"
  u.save!
end

तब वह तुरंत स्पष्ट हो जाएगा। एक पाठक को यह पढ़ने के लिए नहीं होना चाहिए कि ब्लॉक के अंदर क्या है, यह जानने के लिए कि एक उदाहरण userबनाया गया है।


3
@ मैट: और ब्लॉक के अपना काम करने के बाद प्रक्रिया में की गई किसी भी वैरिएबल परिभाषा को भी छोड़ दें। और ऑब्जेक्ट पर सिर्फ एक विधि का आह्वान होना चाहिए, आप लिख सकते हैंUser.new.tap &:foobar
बोरिस स्टिटनिक जूल 5'13

28
मुझे यह उपयोग बहुत सम्मोहक नहीं लगता - यकीनन यह अधिक पठनीय नहीं है, इसीलिए इस पृष्ठ पर थे। एक मजबूत पठनीयता के तर्क के बिना, मैंने गति की तुलना की। मेरे परीक्षणों से उपरोक्त सरल कार्यान्वयन के लिए 45% अतिरिक्त रनटाइम का संकेत मिलता है, क्योंकि वस्तु पर बसने वालों की संख्या कम हो जाती है - उनमें से लगभग 10 या उससे अधिक और रनटाइम अंतर नगण्य है (वाईएमएमवी)। डिबगिंग के दौरान तरीकों की श्रृंखला में 'टैपिंग' एक जीत की तरह लगता है, अन्यथा मुझे मनाने के लिए मुझे और अधिक की आवश्यकता है।
दिनमान 2022

7
मुझे लगता है कि user = User.create!(username: 'foobar')इस मामले में कुछ स्पष्ट और सबसे छोटा होगा :) - प्रश्न से अंतिम उदाहरण।
ली

4
यह उत्तर अपने आप में विरोधाभास है, और इस तरह इसका कोई मतलब नहीं है। "सिर्फ नाम का उदाहरण बनाने" की तुलना में अधिक हो रहा है user। इसके अलावा, यह तर्क कि "एक पाठक को यह पढ़ने के लिए नहीं होना चाहिए कि ब्लॉक के अंदर क्या है यह जानने के लिए कि एक उदाहरण userबनाया गया है।" कोई वज़न नहीं रखता है, क्योंकि पहले कोड ब्लॉक में, पाठक को केवल पहली पंक्ति को पढ़ने की आवश्यकता होती है "यह जानने के लिए कि एक उदाहरण userबनाया गया है।"
जैक्सन

5
मैं यहाँ क्यों हूँ? हम सब यहां क्यों खोज रहे हैं कि टैप क्या है।
एडी

37

नल का उपयोग करने का एक और मामला इसे वापस करने से पहले ऑब्जेक्ट पर हेरफेर करना है।

इसलिए इसके बजाय:

def some_method
  ...
  some_object.serialize
  some_object
end

हम अतिरिक्त लाइन बचा सकते हैं:

def some_method
  ...
  some_object.tap{ |o| o.serialize }
end

कुछ स्थिति में यह तकनीक अधिक एक पंक्ति को बचा सकती है और कोड को अधिक कॉम्पैक्ट बना सकती है।


24
मैं और भी अधिक कठोर हो जाएगा:some_object.tap(&:serialize)
आमीनारिणी

28

नल का उपयोग करना, जैसा कि ब्लॉगर ने किया था, बस एक सुविधा विधि है। यह आपके उदाहरण में ओवरकिल हो सकता है, लेकिन ऐसे मामलों में जहां आप उपयोगकर्ता के साथ चीजों का एक गुच्छा करना चाहते हैं, नल यकीनन एक क्लीनर दिखने वाला इंटरफ़ेस प्रदान कर सकते हैं। इसलिए, शायद यह एक उदाहरण में बेहतर हो सकता है:

user = User.new.tap do |u|
  u.build_profile
  u.process_credit_card
  u.ship_out_item
  u.send_email_confirmation
  u.blahblahyougetmypoint
end

उपरोक्त का उपयोग करना जल्दी से यह देखना आसान बनाता है कि उन सभी तरीकों को एक साथ समूहीकृत किया गया है जिसमें वे सभी एक ही ऑब्जेक्ट (इस उदाहरण में उपयोगकर्ता) का उल्लेख करते हैं। वैकल्पिक होगा:

user = User.new
user.build_profile
user.process_credit_card
user.ship_out_item
user.send_email_confirmation
user.blahblahyougetmypoint

फिर, यह बहस का मुद्दा है - लेकिन यह मामला बनाया जा सकता है कि दूसरा संस्करण थोड़ा गड़बड़ दिखता है, और यह देखने के लिए थोड़ा और मानवीय आश्चर्य होता है कि सभी तरीकों को एक ही वस्तु पर बुलाया जा रहा है।


2
यह सिर्फ एक लंबा उदाहरण है कि ओपी ने पहले से ही अपने सवाल में क्या रखा है, आप अभी भी उपरोक्त सभी के साथ user = User.new, user.do_something, user.do_another_thingकर सकते हैं ... क्या आप इस पर विस्तार कर सकते हैं कि कोई ऐसा क्यों कर सकता है?
मैट

हालांकि उदाहरण अनिवार्य रूप से एक ही है, जब यह इसे लंबे समय तक दिखाता है, तो कोई यह देख सकता है कि इस मामले में नल का उपयोग अधिक सौंदर्यवादी रूप से कैसे हो सकता है। मैं प्रदर्शन संपादित करने में मदद करने के लिए एक संपादन जोड़ूंगा।

मैं इसे नहीं देखता। प्रयोग tapने मेरे अनुभव में कभी कोई लाभ नहीं जोड़ा है। एक स्थानीय userवैरिएबल के साथ बनाना, बनाना और काम करना, मेरी राय में बहुत साफ-सुथरा और पठनीय है।
जाइलज

वे दो समान नहीं हैं। यदि आपने किया u = user = User.newऔर फिर uसेटअप कॉल के लिए उपयोग किया गया तो यह पहले उदाहरण के अनुरूप अधिक होगा।
गेरी

26

यह जंजीरों की श्रृंखला की डिबगिंग के साथ उपयोगी हो सकता है ActiveRecord

User
  .active                      .tap { |users| puts "Users so far: #{users.size}" } 
  .non_admin                   .tap { |users| puts "Users so far: #{users.size}" }
  .at_least_years_old(25)      .tap { |users| puts "Users so far: #{users.size}" }
  .residing_in('USA')

यह श्रृंखला में किसी भी बिंदु पर स्थानीय चर में कुछ भी संग्रह किए बिना डीबग करना आसान बनाता है और न ही मूल कोड में बहुत अधिक फेरबदल की आवश्यकता होती है।

और अंत में, सामान्य कोड निष्पादन को बाधित किए बिना डिबग करने के लिए एक त्वरित और विनीत तरीके के रूप में उपयोग करें :

def rockwell_retro_encabulate
  provide_inverse_reactive_current
  synchronize_cardinal_graham_meters
  @result.tap(&method(:puts))
  # Will debug `@result` just before returning it.
end

14

किसी फ़ंक्शन के भीतर अपने उदाहरण की कल्पना करें

def make_user(name)
  user = User.new
  user.username = name
  user.save!
end

उस दृष्टिकोण के साथ एक बड़ा रखरखाव जोखिम है, मूल रूप से निहित वापसी मूल्य

उस कोड में आप save!सहेजे गए उपयोगकर्ता को वापस करने पर निर्भर करते हैं । लेकिन अगर आप एक अलग बत्तख का उपयोग करते हैं (या आपका वर्तमान एक विकसित होता है) तो आपको एक पूर्ण स्थिति रिपोर्ट जैसी अन्य सामग्री मिल सकती है। इसलिए बतख में परिवर्तन कोड को तोड़ सकता है, ऐसा कुछ जो अगर आप सादे के साथ वापसी मूल्य सुनिश्चित करते हैं तो ऐसा नहीं होगाuser या उपयोग नल के ।

मैंने इस तरह की दुर्घटनाओं को अक्सर देखा है, विशेष रूप से उन कार्यों के साथ जहां वापसी मूल्य आमतौर पर एक अंधेरे छोटी गाड़ी के कोने को छोड़कर उपयोग नहीं किया जाता है।

निहित वापसी मूल्य उन चीजों में से एक है, जहां newbies प्रभाव को ध्यान दिए बिना अंतिम पंक्ति के बाद नए कोड को जोड़ने वाली चीजों को तोड़ते हैं। वे यह नहीं देखते कि उपरोक्त कोड का वास्तव में क्या मतलब है:

def make_user(name)
  user = User.new
  user.username = name
  return user.save!       # notice something different now?
end

1
आपके दो उदाहरणों में बिल्कुल कोई अंतर नहीं है। क्या आपके लौटने का मतलब था user?
ब्रायन ऐश

1
यह उनकी बात थी: उदाहरण बिल्कुल समान हैं, एक वापसी के बारे में स्पष्ट है। उनका कहना था कि नल का उपयोग करने से इस प्रकार बचा जा सकता है:User.new.tap{ |u| u.username = name; u.save! }
मोटापा

14

यदि आप उपयोगकर्ता नाम सेट करने के बाद उपयोगकर्ता को वापस करना चाहते हैं तो आपको करना होगा

user = User.new
user.username = 'foobar'
user

tapआप के साथ कि अजीब वापसी बचा सकता है

User.new.tap do |user|
  user.username = 'foobar'
end

1
यह Object#tapमेरे लिए सबसे आम उपयोग का मामला है।
लिंडसी साइमन

1
खैर, आपने कोड की शून्य लाइनों को सहेज लिया है, और अब, जब यह वापस आता है, तो इसके लिए विधि के अंत को देखते हुए, मुझे यह देखने के लिए स्कैन करना होगा कि ब्लॉक एक # ब्लॉक है। यकीन नहीं होता कि यह किसी भी तरह की जीत है।
इरोंगेज़.कॉम

शायद, लेकिन यह आसानी user = User.new.tap {|u| u.username = 'foobar' }
लेकोस्टेनोकोडर

11

इसके परिणामस्वरूप कम-क्लॉट किए गए कोड होते हैं क्योंकि चर का दायरा केवल उस हिस्से तक सीमित होता है जहां इसकी वास्तव में आवश्यकता होती है। इसके अलावा, ब्लॉक के भीतर इंडेंटेशन संबंधित कोड को एक साथ रखकर कोड को अधिक पठनीय बनाता है।

का विवरण tapकहता है :

ब्लॉक करने के लिए स्वयं को पैदावार देता है, और फिर स्व वापस करता है। इस पद्धति का प्राथमिक उद्देश्य एक श्रृंखला श्रृंखला में "टैप करना" है, ताकि श्रृंखला के भीतर मध्यवर्ती परिणामों पर संचालन किया जा सके।

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

  1. एक तत्व को कुछ शर्तों के आधार पर एक सरणी में जोड़ें

    %w(
    annotations
    ...
    routes
    tmp
    ).tap { |arr|
      arr << 'statistics' if Rake.application.current_scope.empty?
    }.each do |task|
      ...
    end
  2. किसी सरणी को आरम्भ करना और उसे वापस करना

    [].tap do |msg|
      msg << "EXPLAIN for: #{sql}"
      ...
      msg << connection.explain(sql, bind)
    end.join("\n")
  3. कोड को और अधिक पठनीय बनाने के लिए वाक्यविन्यास चीनी के रूप में - कोई कह सकता है, उदाहरण के लिए, चर का उपयोग hashऔरserver कोड को स्पष्ट करने का इरादा बनाता है।

    def select(*args, &block)
        dup.tap { |hash| hash.select!(*args, &block) }
    end
  4. नई बनाई गई वस्तुओं पर तरीकों का आरंभ / आह्वान करें।

    Rails::Server.new.tap do |server|
       require APP_PATH
       Dir.chdir(Rails.application.root)
       server.start
    end

    नीचे परीक्षण फ़ाइल से एक उदाहरण है

    @pirate = Pirate.new.tap do |pirate|
      pirate.catchphrase = "Don't call me!"
      pirate.birds_attributes = [{:name => 'Bird1'},{:name => 'Bird2'}]
      pirate.save!
    end
  5. yieldअस्थायी चर का उपयोग किए बिना कॉल के परिणाम पर कार्य करने के लिए।

    yield.tap do |rendered_partial|
      collection_cache.write(key, rendered_partial, cache_options)
    end

9

@ आरा के उत्तर पर एक भिन्नता:

जैसा कि पहले ही उल्लेख किया गया है, का उपयोग करते हुए tap अपने कोड के इरादे का पता लगाने में मदद करता है (जबकि जरूरी नहीं कि इसे और अधिक कॉम्पैक्ट बनाया जाए)।

निम्नलिखित दो कार्य समान रूप से लंबे हैं, लेकिन पहले एक में आपको यह जानने के लिए अंत के माध्यम से पढ़ना होगा कि मैंने शुरुआत में एक खाली हाश को क्यों शुरू किया।

def tapping1
  # setting up a hash
  h = {}
  # working on it
  h[:one] = 1
  h[:two] = 2
  # returning the hash
  h
end

इधर, दूसरी ओर, आप शुरू से ही जानते हैं कि हैश को इनिशियलाइज़ किया जाना ब्लॉक का आउटपुट होगा (और, इस मामले में, फ़ंक्शन का रिटर्न वैल्यू)।

def tapping2
  # a hash will be returned at the end of this block;
  # all work will occur inside
  Hash.new.tap do |h|
    h[:one] = 1
    h[:two] = 2
  end
end

tapअधिक सम्मोहक तर्क के लिए बनाता है के इस आवेदन । मैं दूसरों से सहमत हूं कि जब आप देखते हैं user = User.new, तो इरादा पहले से ही स्पष्ट है। एक अनाम डेटा संरचना, हालांकि, किसी भी चीज के लिए इस्तेमाल की जा सकती है, और tapविधि कम से कम यह स्पष्ट करती है कि डेटा संरचना विधि का फोकस है।
volx757

यकीन नहीं है कि यह उदाहरण किसी भी बेहतर है और इस मामले में बेंचमार्किंग बनाम def tapping1; {one: 1, two: 2}; endशो का उपयोग .tapकरना लगभग 50% धीमा है
लैकोस्टेनकोडर

9

यह कॉल चेनिंग के लिए एक सहायक है। यह दिए गए ब्लॉक में अपनी वस्तु को भेजता है और ब्लॉक खत्म होने के बाद, वस्तु लौटाता है:

an_object.tap do |o|
  # do stuff with an_object, which is in o #
end  ===> an_object

लाभ यह है कि नल हमेशा उस वस्तु को लौटाता है जिस पर उसे कॉल किया जाता है, भले ही ब्लॉक कुछ और परिणाम देता हो। इस प्रकार आप प्रवाह को तोड़े बिना एक मौजूदा विधि पाइपलाइन के बीच में एक नल ब्लॉक डाल सकते हैं।


8

मैं कहूंगा कि उपयोग करने का कोई फायदा नहीं है tap@Sawa बताते ही एकमात्र संभावित लाभ , और मैं उद्धृत करता हूं: "एक पाठक को यह पढ़ने के लिए नहीं होना चाहिए कि ब्लॉक के अंदर क्या है, यह जानने के लिए कि एक उदाहरण उपयोगकर्ता बनाया गया है।" हालाँकि, उस बिंदु पर यह तर्क दिया जा सकता है कि यदि आप गैर-सरलीकृत रिकॉर्ड निर्माण तर्क कर रहे हैं, तो आपके इरादे को उस तर्क को अपनी विधि में निकालने से बेहतर संचार होगा।

मैं इस राय को मानता हूं कि tapकोड की पठनीयता पर एक अनावश्यक बोझ है, और इसे एक्स्ट्रेक्ट मेथड की तरह, बिना बेहतर तकनीक के, या बिना प्रतिस्थापित किया जा सकता है।

जबकि tapएक सुविधा विधि है, यह व्यक्तिगत प्राथमिकता भी है। दे दो tapएक कोशिश। फिर टैप का उपयोग किए बिना कुछ कोड लिखें, देखें कि क्या आपको एक तरह से दूसरे पर पसंद है।


4

वहाँ उपयोग और स्थानों की संख्या हो सकती है जहाँ हम उपयोग करने में सक्षम हो सकते हैं tap। अब तक मैंने केवल 2 उपयोगों के बाद पाया हैtap

1) इस पद्धति का प्राथमिक उद्देश्य श्रृंखला के भीतर मध्यवर्ती परिणामों पर संचालन करने के लिए, विधि श्रृंखला में टैप करना है। अर्थात

(1..10).tap { |x| puts "original: #{x.inspect}" }.to_a.
    tap    { |x| puts "array: #{x.inspect}" }.
    select { |x| x%2 == 0 }.
    tap    { |x| puts "evens: #{x.inspect}" }.
    map    { |x| x*x }.
    tap    { |x| puts "squares: #{x.inspect}" }

2) क्या आपने कभी अपने आप को किसी वस्तु पर एक विधि कहते हुए पाया, और वापसी मूल्य वह नहीं है जो आप इसे चाहते थे? हो सकता है कि आप हैश में संग्रहीत मापदंडों के एक सेट में एक मनमाना मूल्य जोड़ना चाहते थे। आप इसे हैश के साथ अपडेट करते हैं । [] , लेकिन आपको परम हैश के बजाय बार मिल जाता है , इसलिए आपको इसे स्पष्ट रूप से वापस करना होगा। अर्थात

def update_params(params)
  params[:foo] = 'bar'
  params
end

यहां इस स्थिति को दूर करने के लिए, tapविधि खेलने में आती है। बस इसे ऑब्जेक्ट पर कॉल करें, फिर उस कोड के साथ एक ब्लॉक टैप करें जिसे आप चलाना चाहते थे। ऑब्जेक्ट को ब्लॉक पर उतारा जाएगा, फिर लौटा दिया जाएगा। अर्थात

def update_params(params)
  params.tap {|p| p[:foo] = 'bar' }
end

दर्जनों अन्य उपयोग के मामले हैं, उन्हें स्वयं खोजने का प्रयास करें :)

स्रोत:
1) एपीआई डॉक ऑब्जेक्ट टैप
2) पांच-रूबी-तरीके-आप-का-उपयोग कर रहे हैं


3

आप सही हैं: का उपयोग करें tap आपके उदाहरण का व्यर्थ की तरह है और शायद आपके विकल्पों से कम साफ है।

रेबिजेल नोट के रूप में, tap बस एक सुविधा विधि है, जिसका उपयोग अक्सर वर्तमान वस्तु के लिए एक छोटा संदर्भ बनाने के लिए किया जाता है।

tapडिबगिंग के लिए एक अच्छा उपयोग मामला है: आप ऑब्जेक्ट को संशोधित कर सकते हैं, वर्तमान स्थिति को प्रिंट कर सकते हैं, फिर उसी ब्लॉक में ऑब्जेक्ट को संशोधित कर सकते हैं। उदाहरण के लिए यहाँ देखें: http://moonbase.rydia.net/mental/blog/programming/eavesdropping-on-expressions

मैं कभी-कभी tapवर्तमान वस्तु को वापस करते हुए सशर्त रूप से जल्दी लौटने के लिए अंदर के तरीकों का उपयोग करना पसंद करता हूं ।


यह डॉक्स में उल्लिखित एप्लिकेशन भी है: ruby-doc.org/core-2.1.3/Object.html#method-i-tap
Ciro Santilli 郝海东 mentioned mentioned mentioned 法轮功

3

एक उपकरण है जिसे फॉग कहा जाता है जो मापता है कि किसी विधि को पढ़ना कितना मुश्किल है। "स्कोर जितना अधिक होगा, कोड में उतना ही अधिक दर्द होगा।"

def with_tap
  user = User.new.tap do |u|
    u.username = "foobar"
    u.save!
  end
end

def without_tap
  user = User.new
  user.username = "foobar"
  user.save!
end

def using_create
  user = User.create! username: "foobar"
end

और फ़्लॉग के परिणाम के अनुसार विधि tapको पढ़ना सबसे कठिन है (और मैं इससे सहमत हूं)

 4.5: main#with_tap                    temp.rb:1-4
 2.4:   assignment
 1.3:   save!
 1.3:   new
 1.1:   branch
 1.1:   tap

 3.1: main#without_tap                 temp.rb:8-11
 2.2:   assignment
 1.1:   new
 1.1:   save!

 1.6: main#using_create                temp.rb:14-16
 1.1:   assignment
 1.1:   create!

1

आप नल का उपयोग करके अपने कोड को अधिक मॉड्यूलर बना सकते हैं, और स्थानीय चर का बेहतर प्रबंधन प्राप्त कर सकते हैं। उदाहरण के लिए, निम्न कोड में, आपको विधि के दायरे में, नई बनाई गई वस्तु के लिए एक स्थानीय चर निर्दिष्ट करने की आवश्यकता नहीं है। ध्यान दें कि ब्लॉक वैरिएबल, यू , ब्लॉक के भीतर स्कोप किया गया है। यह वास्तव में माणिक कोड की सुंदरियों में से एक है।

def a_method
  ...
  name = "foobar"
  ...
  return User.new.tap do |u|
    u.username = name
    u.save!
  end
end

1

रेल में हम tapश्वेतसूची मापदंडों का स्पष्ट रूप से उपयोग कर सकते हैं :

def client_params
    params.require(:client).permit(:name).tap do |whitelist|
        whitelist[:name] = params[:client][:name]
    end
end

1

मैं एक और उदाहरण दूंगा जिसका मैंने उपयोग किया है। मेरे पास एक तरीका user_params है जो उपयोगकर्ता के लिए सहेजने के लिए आवश्यक पैरामेट्स लौटाता है (यह एक रेल परियोजना है)

def user_params
  params.require(:user).permit(
    :first_name,
    :last_name,
    :email,
    :address_attributes
  )
end

आप देख सकते हैं कि मैं कुछ भी नहीं लौटा सकता हूँ, लेकिन माणिक अंतिम पंक्ति का आउटपुट लौटा सकता है।

फिर, कुछ समय बाद, मुझे सशर्त रूप से एक नई विशेषता जोड़ने की आवश्यकता थी। तो, मैंने इसे कुछ इस तरह से बदल दिया:

def user_params 
  u_params = params.require(:user).permit(
    :first_name, 
    :last_name, 
    :email,
    :address_attributes
  )
  u_params[:time_zone] = address_timezone if u_params[:address_attributes]
  u_params
end

यहां हम स्थानीय वैरिएबल को हटाने और रिटर्न को हटाने के लिए टैप का उपयोग कर सकते हैं:

def user_params 
  params.require(:user).permit(
    :first_name, 
    :last_name, 
    :email,
    :address_attributes
  ).tap do |u_params|
    u_params[:time_zone] = address_timezone if u_params[:address_attributes]
  end
end

1

दुनिया में जहां कार्यात्मक प्रोग्रामिंग पैटर्न एक सबसे अच्छा अभ्यास (होता जा रहा है में https://maryrosecook.com/blog/post/a-practical-introduction-to-functional-programming ), आप देख सकते हैं tapएक के रूप में, mapएक भी मूल्य पर, वास्तव में , एक परिवर्तन श्रृंखला पर अपने डेटा को संशोधित करने के लिए।

transformed_array = array.map(&:first_transformation).map(&:second_transformation)

transformed_value = item.tap(&:first_transformation).tap(&:second_transformation)

itemयहां कई बार घोषणा करने की जरूरत नहीं है।


0

अंतर क्या है?

कोड पठनीयता के संदर्भ में अंतर विशुद्ध रूप से शैलीगत है।

कोड के माध्यम से चलो:

user = User.new.tap do |u|
  u.username = "foobar"
  u.save!
end

प्रमुख बिंदु:

  • ध्यान दें कि कैसे u चर को अब ब्लॉक पैरामीटर के रूप में उपयोग किया जाता है?
  • ब्लॉक होने के बाद, user चर को अब एक उपयोगकर्ता (उपयोगकर्ता नाम के साथ: 'फ़ॉबोर', और जिसे भी सहेजा जाता है) को इंगित करना चाहिए।
  • यह सिर्फ सुखद और पढ़ने में आसान है।

एपीआई प्रलेखन

स्रोत कोड का संस्करण पढ़ने में आसान है:

class Object
  def tap
    yield self
    self
  end
end

अधिक जानकारी के लिए, ये लिंक देखें:

https://apidock.com/ruby/Object/tap

http://ruby-doc.org/core-2.2.3/Object.html#method-i-tap

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.