রুবিতে ট্যাপ পদ্ধতির সুবিধা


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
বরিস স্ট্যাটনিকিকি

28
আমি এই ব্যবহারটি খুব জোরালোভাবে খুঁজে পাই না - যুক্তিযুক্তভাবে আর কোনও পাঠযোগ্য নয়, সে কারণেই এই পৃষ্ঠায় ছিল। শক্তিশালী পাঠযোগ্যতার যুক্তি ছাড়াই আমি গতির সাথে তুলনা করেছি। আমার পরীক্ষাগুলি উপরের সাধারণ বাস্তবায়নের জন্য 45% অতিরিক্ত রানটাইম সূচিত করে, বস্তুতে সেটার সংখ্যা বৃদ্ধি হ্রাস হ্রাস পাচ্ছে - প্রায় 10 বা তার বেশি এবং রানটাইম পার্থক্য নগণ্য (ওয়াইএমএমভি)। ডিবাগিংয়ের সময় পদ্ধতিগুলির শৃঙ্খলে 'ট্যাপ করা' জয়ের মতো মনে হয়, অন্যথায় আমাকে রাজি করার জন্য আমার আরও বেশি প্রয়োজন।
dinman2022

7
আমি মনে করি এরকম কিছু user = User.create!(username: 'foobar')এই ক্ষেত্রে পরিষ্কার এবং সংক্ষিপ্ত হবে :) - প্রশ্নটির শেষ উদাহরণ।
লি

4
এই উত্তরটি নিজেই স্ববিরোধী, এবং এইভাবে তা বোঝায় না। "কেবলমাত্র নামকরণের উদাহরণ তৈরি করা" এর চেয়ে আরও বেশি কিছু ঘটছে user। এছাড়াও, একটি যুক্তি তৈরি হয়েছে তা জানতে "একটি পাঠককে ব্লকের অভ্যন্তরে কী রয়েছে তা পড়তে হবে না the" এই যুক্তিটিও 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ভেরিয়েবল তৈরি করা এবং এর সাথে কাজ করা আমার মতে অনেক পরিষ্কার এবং পাঠযোগ্য।
gylaz

এই দুটি সমতুল্য নয়। আপনি যদি সেটআপ কলগুলির জন্য করেন 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বা ট্যাপ ব্যবহার করে ফেরতের মান নিশ্চিত করেন তবে তা ঘটবে না ।

আমি প্রায়শই এই জাতীয় দুর্ঘটনা দেখেছি, বিশেষত এমন ফাংশনগুলির সাথে যেখানে ফিরতি মান সাধারণত একটি গা dark় বগী কোণার ব্যতীত ব্যবহৃত হয় না।

অন্তর্নিহিত রিটার্ন মান হ'ল সেই জিনিসগুলির মধ্যে একটি যেখানে 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
ঠিক আছে, আপনি কোডের শূন্য রেখাগুলি সংরক্ষণ করেছেন, এবং এখন এটি কীভাবে ফিরে আসে তার পদ্ধতির শেষের দিকে তাকালে, ব্লকটি একটি # ট্যাপ ব্লক কিনা তা দেখতে আমাকে আবার স্ক্যান আপ করতে হবে। নিশ্চিত নয় এটি কোনও ধরণের জয়।
ইরঙ্গাজ.কম

সম্ভবত তবে এটি সহজেই 1 লাইনার হতে পারে user = User.new.tap {|u| u.username = 'foobar' }
lacostenycoder

11

এটি কম-ক্লিটেড কোডের ফলাফল দেয় কারণ ভেরিয়েবলের সুযোগটি কেবলমাত্র সেই অংশে সীমাবদ্ধ যেখানে এটি সত্যই প্রয়োজন। এছাড়াও, ব্লকের অন্তর্ভুক্ত ইনডেন্টেশন প্রাসঙ্গিক কোড একসাথে রেখে কোডটিকে আরও পঠনযোগ্য করে তোলে।

বিবরণ tapবলেছেন :

ব্লকের মধ্যে স্বয়ং উত্পাদন করে এবং তারপরে স্বদান দেয়। এই পদ্ধতির প্রাথমিক উদ্দেশ্য হল চেইনের মধ্যে অন্তর্বর্তী ফলাফলগুলিতে ক্রিয়াকলাপ সম্পাদনের জন্য একটি পদ্ধতি শৃঙ্খলে "ট্যাপ করা"।

যদি আমরা ব্যবহারের জন্য রেলগুলির উত্স কোডটি অনুসন্ধানtap করি তবে আমরা কিছু আকর্ষণীয় ব্যবহারগুলি খুঁজে পেতে পারি can নীচে কয়েকটি আইটেম রয়েছে (সম্পূর্ণ তালিকা নয়) যা সেগুলি কীভাবে ব্যবহার করবেন সে সম্পর্কে আমাদের কয়েকটি ধারণা দেবে:

  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

সুবিধাটি হ'ল ট্যাপ সর্বদা তার কল করা বস্তুটি ফিরিয়ে দেয়, এমনকি ব্লকটি অন্য কোনও ফলাফলও দেয়। এইভাবে আপনি প্রবাহকে ভঙ্গ না করে কোনও বিদ্যমান পদ্ধতির পাইপলাইনের মাঝখানে একটি ট্যাপ ব্লক sertোকাতে পারেন।


8

আমি বলব যে ব্যবহার করার কোনও সুবিধা নেই tap@ সাওয়া দেখায় কেবল সম্ভাব্য সুবিধা হ'ল, এবং আমি উদ্ধৃত করেছি: "একটি পাঠককে ব্লকের ভিতরে থাকা বিষয়গুলি পড়তে হবে না তা জানতে যে কোনও উদাহরণ ব্যবহারকারী তৈরি হয়েছে" " যাইহোক, এই মুহূর্তে যুক্তি তৈরি করা যেতে পারে যে আপনি যদি সরল-রেকর্ড তৈরির যুক্তিটি করেন তবে আপনার উদ্দেশ্যটি সেই পদ্ধতিটিকে তার নিজস্ব পদ্ধতিতে বের করে আরও ভালভাবে জানানো হবে।

আমি এই মতামতটি ধরে রেখেছি যে 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/eavesDPping-on-expressionions

আমি tapঅন্যথায় বর্তমান অবজেক্টটি ফেরত দেওয়ার সময় শর্তসাপেক্ষে শীঘ্রই ফিরে আসার জন্য অভ্যন্তরীণ পদ্ধতিগুলি ব্যবহার করতে চাই ।


এই আবেদন ডক্স উল্লেখ করা হয়: ruby-doc.org/core-2.1.3/Object.html#method-i-tap
সিরো Santilli郝海东冠状病六四事件法轮功

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

আপনি ট্যাপ ব্যবহার করে আপনার কোডগুলি আরও মডুলার করতে পারেন এবং স্থানীয় ভেরিয়েবলগুলির আরও ভাল পরিচালনা অর্জন করতে পারেন। উদাহরণস্বরূপ, নিম্নলিখিত কোডে, আপনাকে পদ্ধতির সুযোগে নতুন তৈরি করা অবজেক্টের জন্য স্থানীয় ভেরিয়েবল নির্ধারণের প্রয়োজন হবে না। মনে রাখবেন যে ব্লক ভেরিয়েবল, u , ব্লকের মধ্যে রয়েছে। এটি আসলে রুবি কোডের অন্যতম সৌন্দর্য the

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

আমি অন্য একটি উদাহরণ দেব যা আমি ব্যবহার করেছি। আমার কাছে একটি পদ্ধতি ব্যবহারকারী_প্রেম রয়েছে যা ব্যবহারকারীর জন্য সংরক্ষণ করার জন্য প্রয়োজনীয় প্যারামগুলি ফেরত দেয় (এটি একটি রেল প্রকল্প)

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-intr پيداوار-to-functional-programming ), আপনি দেখতে পাচ্ছেন tap, mapএকক মান হিসাবে, সত্যই , একটি রূপান্তর চেইনে আপনার ডেটা পরিবর্তন করতে ify

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

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