কেন রুবি সমর্থন পদ্ধতি ওভারলোডিং হয় না?


146

রুবির সাহায্যকারী পদ্ধতির পরিবর্তে বিদ্যমান পদ্ধতিগুলিকে ওভাররাইট করে। ভাষাটি কেন এইভাবে ডিজাইন করা হয়েছিল তা কেউ ব্যাখ্যা করতে পারেন?

উত্তর:


166

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

  1. বিভিন্ন ডেটা ধরণের যুক্তিগুলি যেমন: method(int a, int b) vs method(String a, String b)
  2. আর্গুমেন্টগুলির পরিবর্তনশীল সংখ্যা, যেমন: method(a) vs method(a, b)

রুবি ( ডায়নামিক টাইপড ল্যাঙ্গুয়েজ ) তে ডেটা টাইপ ঘোষণা নেই বলে আমরা প্রথম উপায় ব্যবহার করে পদ্ধতি ওভারলোডিং অর্জন করতে পারি না । সুতরাং উপরের পদ্ধতিটি সংজ্ঞায়িত করার একমাত্র উপায়def(a,b)

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

def method(a); end;
def method(a, b = true); end; # second argument has a default value

method(10)
# Now the method call can match the first one as well as the second one, 
# so here is the problem.

সুতরাং রুবি পদ্ধতিতে একটি পদ্ধতি বজায় রাখা প্রয়োজন একটি অনন্য নাম সহ চেইন আপ চেইন।


22
@ জার্গ ডব্লু মিটাগের উত্তর, নীচে নিচে সমাহিত করা অবশ্যই পড়া দরকার।
ব্যবহারকারী 2398029

1
এবং @ ডেরেক একিনসের উত্তর, আরও সমাহিত, একটি বিকল্প সরবরাহ করে
সাইরিল ডুচন-ডরিস

ভবিষ্যতের রুবিবাদীদের জন্য নোট করুন ... FWIW আপনি চুক্তি রত্ন egonschiele.github.io/contracts.ruby/# মৈথুন- ওভারলোডিংয়ের
ইঞ্জিনিয়ার

214

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

এখন, আপনি যদি করছে না আসলে বিশেষভাবে ওভারলোডিং সম্পর্কে জিজ্ঞাসা করা, কিন্তু হয়তো সম্পর্কে গতিশীল যুক্তি-ভিত্তিক প্রেরণ, তারপর উত্তর কারণ Matz তা বাস্তবায়ন করা হয়নি। কারণ অন্য কেউ এটিকে প্রস্তাব দেওয়ার ব্যাপারে মাথা ঘামায় না। কারণ অন্য কেউ এটিকে বাস্তবায়নের জন্য মাথা ঘামায় না।

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

C #, আপনি আসলে এনকোড করতে কোনো জমিদার রেজল্যুশন, যার মানে C # জমিদার রেজল্যুশন দ্বারা NP-কঠিন মধ্যে 3-স্যাট সমস্যা।

এখন চেষ্টা করুন ডায়নামিক প্রেরণের সাথে, যেখানে আপনার মাথায় রাখতে অতিরিক্ত সময় মাত্রা রয়েছে।

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

তবে আমি গতিশীল তর্ক-ভিত্তিক প্রেরণের কোনও ওও ভাষা জানি না। মার্টিন Odersky বলেছেন যে তিনি পারে Scala আর্গুমেন্ট প্রাপ্ত করতে ভিত্তিক প্রেরণ যোগ করার বিষয়টি বিবেচনা কিন্তু শুধুমাত্র যদি তিনি একই সময়ে ওভারলোডিং অপসারণ করতে পারেন এবং পিছন সামঞ্জস্যপূর্ণ উভয় বিদ্যমান Scala কোডটি ব্যবহার ওভারলোডিং এবং জাভা সঙ্গে সামঞ্জস্যপূর্ণ হতে (তিনি বিশেষত সুইং এবং AWT উল্লিখিত যা জাভা এর পরিবর্তে জটিল ওভারলোডিং নিয়মের প্রতিটি বাজে ডার্ক কর্নারের ক্ষেত্রে বেশ কিছু জটিল কৌশল ব্যবহার করে। আমি রুবির কাছে যুক্তি-ভিত্তিক প্রেরন যোগ করার বিষয়ে আমার কিছু ধারণা পেয়েছি, তবে পিছনে সামঞ্জস্যপূর্ণ পদ্ধতিতে এটি কীভাবে করা যায় তা আমি কখনই বুঝতে পারি না।


5
এটি সঠিক উত্তর। গৃহীত উত্তর ওভারস্প্লিফাইফাই করে। সি # ডিওএস প্যারামিটার এবং alচ্ছিক পরামিতিগুলির নাম দিয়েছে এবং এখনও ওভারলোডিং প্রয়োগ করে, সুতরাং এটি "কার্যকর def method(a, b = true)হবে না, সুতরাং পদ্ধতি ওভারলোডিং অসম্ভব" এর মতো সহজ নয়। এটা না; এটা ঠিক কঠিন। যদিও আমি এই উত্তরটি সত্যিই তথ্যপূর্ণ পেয়েছি।
tandrewnichols

1
@ স্ট্যান্ড্রুনিচলস: ওভারলোড রেজোলিউশন সি # তে "কঠিন" কতটা কঠিন তা কেবল কিছু ধারণা দেওয়ার জন্য… সি # তে ওভারলোড রেজোলিউশন হিসাবে যে কোনও 3-স্যাট সমস্যাটি এনকোড করা সম্ভব এবং সংকলকটি সংকলন সময়ে সমাধান করতে পারে, সুতরাং সি # এনপি-তে ওভারলোড রেজোলিউশন তৈরি করে -হার্ড (3-স্যাট এনপি-সম্পূর্ণ হিসাবে পরিচিত)। এখন কল্পনা করুন যে সংকলনের সময় কল সাইট প্রতি একবার নয় , রানটাইম সময়ে প্রতিটি পদ্ধতি পদ্ধতিতে কল করার জন্য একবার পদ্ধতি পদ্ধতিতে একবার করুন ।
জার্গ ডব্লু মিট্টাগ

1
@ জার্গডব্লিউমিত্যাগ আপনি ওভারলোড রেজোলিউশন মেকানিজমে 3-SAT সমস্যার এনকোডিং দেখানো একটি লিঙ্ক অন্তর্ভুক্ত করতে পারেন?
স্কুইডলি

1
@ মিঃবোনস: ব্লগস.এমএসডন.কম / বি
ডব্লু

2
দেখে মনে হচ্ছে না "ওভারলোডিং" "স্ট্যাটিক যুক্তি-ভিত্তিক প্রেরন" এর প্রতিশব্দ। স্থির যুক্তি-ভিত্তিক প্রেরণ কেবল ওভারলোডিংয়ের সর্বাধিক সাধারণ প্রয়োগ। ওভারলোডিং একটি বাস্তবায়ন অজ্ঞাবল শব্দ, যার অর্থ "একই পদ্ধতির নাম তবে একই সুযোগে বিভিন্ন বাস্তবায়ন"।
স্নোভিটি

85

আমি অনুমান করি আপনি এটি করার ক্ষমতা খুঁজছেন:

def my_method(arg1)
..
end

def my_method(arg1, arg2)
..
end

রুবি একে অন্যভাবে সমর্থন করে:

def my_method(*args)
  if args.length == 1
    #method 1
  else
    #method 2
  end
end

একটি সাধারণ প্যাটার্ন হ্যাশ হিসাবে বিকল্পগুলিতে পাস করা হয়:

def my_method(options)
    if options[:arg1] and options[:arg2]
      #method 2
    elsif options[:arg1]
      #method 1
    end
end

my_method arg1: 'hello', arg2: 'world'

আশা করি এইটি কাজ করবে


15
আমাদের মধ্যে অনেকে কেবল কী জানতে চান তা সরবরাহের জন্য +1: রুবি পদ্ধতিতে পরিবর্তনশীল সংখ্যক আর্গুমেন্টের সাথে কীভাবে কাজ করবেন।
ashes999

3
এই উত্তরটি optionচ্ছিক যুক্তি সম্পর্কিত অতিরিক্ত তথ্য থেকে উপকৃত হতে পারে। (এবং সম্ভবত যুক্তিগুলির নামও দিয়েছে, এখন যে এটি একটি জিনিস))
আজেদি 32

9

স্ট্যাটিক টাইপিং সহ এমন একটি ভাষাতে ওভারলোডিং পদ্ধতিটি বোঝায়, যেখানে আপনি বিভিন্ন ধরণের আর্গুমেন্টের মধ্যে পার্থক্য করতে পারেন

f(1)
f('foo')
f(true)

পাশাপাশি বিভিন্ন সংখ্যার যুক্তিগুলির মধ্যে

f(1)
f(1, 'foo')
f(1, 'foo', true)

রুবিতে প্রথম পার্থক্য নেই। রুবি ডায়নামিক টাইপিং বা "হাঁসের টাইপিং" ব্যবহার করে। দ্বিতীয় পার্থক্যটি ডিফল্ট আর্গুমেন্ট বা আর্গুমেন্টগুলির সাথে কাজ করে পরিচালনা করা যায়:

def f(n, s = 'foo', flux_compensator = true)
   ...
end


def f(*args)
  case args.size
  when  
     ...
  when 2
    ...
  when 3
    ...
  end
end

দৃ strong় টাইপিংয়ের সাথে এর কোনও যোগসূত্র নেই। সব পরে রুবি দৃed়ভাবে টাইপ করা হয়
জার্গ ডব্লু মিত্তাগ

8

এটি কেন রুবির পদ্ধতিতে ওভারলোডিং নেই এমন প্রশ্নের উত্তর দেয় না, তবে তৃতীয় পক্ষের লাইব্রেরি এটি সরবরাহ করতে পারে।

Contracts.ruby গ্রন্থাগার ওভারলোডিং পারেন। টিউটোরিয়াল থেকে অভিযোজিত উদাহরণ:

class Factorial
  include Contracts

  Contract 1 => 1
  def fact(x)
    x
  end

  Contract Num => Num
  def fact(x)
    x * fact(x - 1)
  end
end

# try it out
Factorial.new.fact(5)  # => 120

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

আপনি যদিও এটি ব্যবহার করে কর্মক্ষমতা হ্রাস পাবেন; আপনি কতটা সহ্য করতে পারবেন তা সিদ্ধান্ত নিতে আপনাকে বেঞ্চমার্ক চালাতে হবে।


1
যে কোনও ধরণের আইও সহ বাস্তব বিশ্বের অ্যাপ্লিকেশনগুলিতে আপনার কাছে কেবলমাত্র 0.1-10% (আইও এর ধরণের উপর নির্ভর করে) ধীর গতিতে হবে।
ওয়াটারলিঙ্ক 20'15

1

আমি প্রায়শই নিম্নলিখিত কাঠামোটি করি:

def method(param)
    case param
    when String
         method_for_String(param)
    when Type1
         method_for_Type1(param)

    ...

    else
         #default implementation
    end
end

এটি অবজেক্টটির ব্যবহারকারীকে পরিষ্কার এবং পরিষ্কার পদ্ধতি_নাম: পদ্ধতিটি ব্যবহার করতে দেয় তবে তিনি যদি কার্যকর প্রয়োগটি অনুকূল করতে চান তবে তিনি সরাসরি সঠিক পদ্ধতিতে কল করতে পারেন।

এছাড়াও, এটি আপনার পরীক্ষাকে ক্লিয়ার এবং বেটার করে তোলে।


1

প্রশ্নের পাশে কেন ইতিমধ্যে দুর্দান্ত উত্তর রয়েছে। তবে, যদি কেউ অন্যান্য সমাধানগুলি সন্ধান করে ফাংশনাল-রুবি রত্ন যা এলিক্সির প্যাটার্ন মেলানো বৈশিষ্ট্যগুলি দ্বারা অনুপ্রাণিত হয় check

 class Foo
   include Functional::PatternMatching

   ## Constructor Over loading
   defn(:initialize) { @name = 'baz' }
   defn(:initialize, _) {|name| @name = name.to_s }

   ## Method Overloading
   defn(:greet, :male) {
     puts "Hello, sir!"
   }

   defn(:greet, :female) {
     puts "Hello, ma'am!"
   }
 end

 foo = Foo.new or Foo.new('Bar')
 foo.greet(:male)   => "Hello, sir!"
 foo.greet(:female) => "Hello, ma'am!"   
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.