একটি শ্রেণি দেওয়া হয়েছে, দেখুন উদাহরণের পদ্ধতি আছে কিনা (রুবি)


227

আমি রুবিতে জানি যে respond_to?কোনও বস্তুর নির্দিষ্ট পদ্ধতি আছে কিনা তা পরীক্ষা করতে আমি ব্যবহার করতে পারি ।

তবে, ক্লাসটি দেওয়া হলে, উদাহরণটি একটি নির্দিষ্ট পদ্ধতি আছে কিনা তা আমি কীভাবে পরীক্ষা করতে পারি?

যেমন, কিছু

Foo.new.respond_to?(:bar)

তবে আমি মনে করি যে কোনও নতুন উদাহরণ ইনস্ট্যান্ট করার চেয়ে আরও ভাল উপায় হবে।

উত্তর:


364

আমি জানি না কেন সবাই আপনার ব্যবহার করা উচিত instance_methodsএবং include?কখন method_defined?কাজটি করা উচিত তা পরামর্শ দিচ্ছে।

class Test
  def hello; end
end

Test.method_defined? :hello #=> true

বিঃদ্রঃ

আপনি যদি অন্য কোনও ভাষা থেকে রুবিতে আসছেন বা আপনি মনে করেন যে method_definedকেবলমাত্র সেই পদ্ধতিগুলির সাথে আপনি স্পষ্টভাবে সংজ্ঞায়িত করেছেন:

def my_method
end

তারপরে এটি পড়ুন:

রুবিতে, আপনার মডেলের একটি সম্পত্তি (বৈশিষ্ট্য) মূলত একটি পদ্ধতিও। সুতরাং method_defined?বৈশিষ্ট্যগুলির জন্যও সত্য ফিরে আসবে, কেবল পদ্ধতি নয়।

উদাহরণ স্বরূপ:

স্ট্রিং বৈশিষ্ট্যযুক্ত এমন একটি শ্রেণীর উদাহরণ দেওয়া হয়েছে first_name:

<instance>.first_name.class #=> String

<instance>.class.method_defined?(:first_name) #=> true

যেহেতু first_nameএকটি বৈশিষ্ট্য এবং একটি পদ্ধতি (এবং স্ট্রিং টাইপের একটি স্ট্রিং) উভয়ই।


9
method_defined? সর্বোত্তম সমাধান কারণ উদাহরণস্বরূপ রুবি 1.8 এবং 1.9 এর মধ্যে পরিবর্তন হয়েছে thod 1.8 স্ট্রিংগুলির একটি অ্যারে প্রদান করে এবং 1.9 প্রতীকগুলির একটি অ্যারের প্রদান করে। method_defined? 1.8 এবং 1.9 উভয় ক্ষেত্রেই একটি প্রতীক নেয়।
জেসন

2
উল্লেখ করার দরকার নেই: উদাহরণ_মাদৃগণ প্রতিটি কলটিতে একটি নতুন অ্যারে তৈরি করবে এবং সেগুলি: অন্তর্ভুক্ত? তারপরে অ্যারে বলতে হবে। বিপরীতে,: পদ্ধতি_নির্ধারিত? অভ্যন্তরীণভাবে পদ্ধতি অনুসন্ধানের টেবিলগুলি জিজ্ঞাসা করবে (একটি হ্যাশ লুক যা সিতে রয়েছে) এবং কোনও নতুন অবজেক্ট তৈরি না করেই আপনাকে জানায়।
আশের

4
আপনি যখন এটির মতো এটি ব্যবহার করেন তখন কমপক্ষে একটি সুবিধা থাকে String.instance_methods(false).include? :freeze, তবে মিথ্যা যুক্তি freezeস্ট্রিং ক্লাসে পদ্ধতিটি নির্ধারিত কিনা তা ঠিক বলতে পারে । এই ক্ষেত্রে এটি মিথ্যা প্রত্যাবর্তন করবে কারণ freezeস্ট্রিং দ্বারা পদ্ধতিটি কার্নেল মডিউল থেকে উত্তরাধিকার সূত্রে প্রাপ্ত হয়েছে, তবে String.method_defined? :freezeসর্বদা সত্য ফিরে আসবে, যা এইরকম উদ্দেশ্যে খুব বেশি সহায়তা করতে পারে না।
ugoa

1
@ আপনি উদাহরণে উপলব্ধ পদ্ধতি সহ ক্লাসে বিভ্রান্তিকর পদ্ধতিগুলি বানাচ্ছেন। method_defined?ক্লাসে অবশ্যই ব্যবহার করা উচিত (উদাঃ Array), তবে আপনি এটি উদাহরণস্বরূপ ব্যবহার করার চেষ্টা করছেন (উদাহরণস্বরূপ [])
ঘোড়াগুই

নিবন্ধন করুন স্পষ্টতার জন্য আপনাকে ধন্যবাদ, এটি এটি পড়ার ক্ষেত্রে সঠিক ধারণা তৈরি করে। :) আমি আমার মন্তব্য সরিয়েছি যাতে বিভ্রান্ত না হয়।
বেন

45

আপনি method_defined?নিম্নলিখিত হিসাবে ব্যবহার করতে পারেন :

String.method_defined? :upcase # => true

instance_methods.include?প্রত্যেকের তুলনায় অনেক সহজ, পোর্টেবল এবং দক্ষ পরামর্শ দিচ্ছেন বলে মনে হচ্ছে।

মনে রাখবেন যে কোনও শ্রেণীর সাথে কিছু কলগুলিতে গতিময় প্রতিক্রিয়া হয়েছে কিনা তা আপনি জানতে পারবেন না method_missing, উদাহরণস্বরূপ পুনরায় respond_to?সংজ্ঞা দিয়ে, বা রুবি ১.৯.২ থেকে সংজ্ঞা দিয়ে respond_to_missing?


2
মনে রাখবেন যে যদি আপনি হাতে একটি উদাহরণ পেয়ে থাকেন এবং আপনি এটির শ্রেণিটি জানেন না, আপনি করতে পারেনinstance.class.method_defined? :upcase
jaydel

25

আসলে এটি উভয় অবজেক্ট এবং ক্লাসের জন্য কাজ করে না।

এটি করে:

class TestClass
  def methodName
  end
end

সুতরাং প্রদত্ত উত্তরের সাথে, এটি কাজ করে:

TestClass.method_defined? :methodName # => TRUE

কিন্তু এই কাজ করে না:

t = TestClass.new
t.method_defined? : methodName  # => ERROR!

সুতরাং আমি এটি উভয় শ্রেণি এবং অবজেক্টের জন্য ব্যবহার করি:

ক্লাস:

TestClass.methods.include? 'methodName'  # => TRUE

অবজেক্টস:

t = TestClass.new
t.methods.include? 'methodName'  # => TRUE

3
উদাহরণস্বরূপ আপনি `দৃষ্টান্ত।
Luksurious

এটি আপনার রুবি সংস্করণের উপর নির্ভর করে। উপরে এই পদ্ধতিটি 1.8.7 সহ সমস্ত সংস্করণের জন্য কাজ করে।
অ্যালেক্স ভি

10

" একটি ক্লাস দেওয়া, উত্তরটি পদ্ধতি আছে কিনা তা দেখুন (রুবি) " আরও ভাল। স্পষ্টতই রুবির এই বিল্ট-ইন রয়েছে এবং আমি কোনওভাবে এটি মিস করেছি। আমার উত্তর রেফারেন্সের জন্য রেখে গেছে, নির্বিশেষে।

রুবি ক্লাস পদ্ধতিতে সাড়া দেয় instance_methodsএবং public_instance_methods। রুবি ১.৮-এ প্রথম স্ট্রিংয়ের অ্যারেতে সমস্ত উদাহরণ পদ্ধতির নাম তালিকাভুক্ত করে এবং দ্বিতীয়টি এটি সর্বজনীন পদ্ধতিতে সীমাবদ্ধ করে। দ্বিতীয় আচরণটি হ'ল আপনি সম্ভবত যা চান তা respond_to?ডিফল্টরূপে পাবলিক পদ্ধতিতেও সীমাবদ্ধ রাখে।

Foo.public_instance_methods.include?('bar')

রুবি ১.৯-তে যদিও এই পদ্ধতিগুলি প্রতীকগুলির অ্যারে ফিরিয়ে দেয়।

Foo.public_instance_methods.include?(:bar)

আপনি যদি প্রায়শই এটি করার পরিকল্পনা করে থাকেন তবে আপনি Moduleএকটি শর্টকাট পদ্ধতি অন্তর্ভুক্ত করতে বাড়াতে চাইতে পারেন । (এটির Moduleপরিবর্তে এটি নির্ধারণ করা অদ্ভুত বলে মনে হতে পারে Class, তবে যেহেতু instance_methodsপদ্ধতিগুলি যেখানে থাকে , তাই সেই প্যাটার্নের সাথে সঙ্গতি রাখাই ভাল))

class Module
  def instance_respond_to?(method_name)
    public_instance_methods.include?(method_name)
  end
end

আপনি যদি রুবি ১.৮ এবং রুবি ১.৯ উভয়কেই সমর্থন করতে চান তবে পাশাপাশি স্ট্রিং এবং চিহ্ন দুটি অনুসন্ধান করার জন্য যুক্তি যুক্ত করার সুবিধাজনক জায়গা হবে।


1
method_defined?আরও ভাল :)
21:30

@ বন্ধু - ওহ, আমার এবং আমি কোনওভাবে এটি মিস করেছি! xD @ মার্কের উত্তরের পিছনে একটি +1 ফেলেছে এবং এটি মিস হয়েছে তা নিশ্চিত করার জন্য একটি লিঙ্ক যুক্ত করেছে :)
ম্যাচু


3

এটি সর্বোত্তম উপায় কিনা তা নিশ্চিত নন তবে আপনি সর্বদা এটি করতে পারেন:

Foo.instance_methods.include? 'bar'

3

আমি মনে করি method_defined?রেলগুলিতে কিছু সমস্যা আছে । এটি অসঙ্গতিপূর্ণ বা কিছু হতে পারে, সুতরাং আপনি যদি রেলগুলি ব্যবহার করেন তবে এখান থেকে কিছু ব্যবহার করা ভাল attribute_method?(attribute)

অ্যাক্টিভেকর্ড ক্লাসে " মেথড_ডিফাইন্ডের জন্য পরীক্ষা করা? ইনস্ট্যান্টেশন না হওয়া পর্যন্ত কাজ করে না " অসঙ্গতি সম্পর্কে প্রশ্ন।


3

যদি আপনি পরীক্ষা করে দেখছেন যে কোনও বস্তু বিভিন্ন পদ্ধতিতে প্রতিক্রিয়া জানাতে পারে তবে আপনি এর মতো কিছু করতে পারেন:

methods = [:valid?, :chase, :test]

def has_methods?(something, methods)
  methods & something.methods == methods
end

methods & something.methodsতাদের সাধারণ / মিলে উপাদানে দুইটি অ্যারের যোগদান করবেন। কিছুর.বিধির মধ্যে আপনি যে পদ্ধতিগুলি পরীক্ষা করছেন তার সবকটিই এতে অন্তর্ভুক্ত রয়েছে, এটি সমান পদ্ধতির। উদাহরণ স্বরূপ:

[1,2] & [1,2,3,4,5]
==> [1,2]

সুতরাং

[1,2] & [1,2,3,4,5] == [1,2]
==> true

এই পরিস্থিতিতে আপনি প্রতীক ব্যবহার করতে চান, কারণ আপনি যখন ["my", "methods"]


2

klass.instance_methods.include :method_nameবা "method_name", আমার মনে হয় রুবি সংস্করণ অনুসারে।


2
class Foo
 def self.fclass_method
 end
 def finstance_method
 end
end

foo_obj = Foo.new
foo_obj.class.methods(false)
=> [:fclass_method] 

foo_obj.class.instance_methods(false)
=> [:fclass_method] 

আশা করি এটি আপনাকে সহায়তা করবে!


1

আমার ক্ষেত্রে রুবি 2.5.3.3 এর সাথে কাজ করে নিম্নলিখিত বাক্যগুলি পুরোপুরি কাজ করেছে:

value = "hello world"

value.methods.include? :upcase

এটি একটি বুলিয়ান মানটি সত্য বা মিথ্যা ফিরিয়ে দেবে।


1

যদিও respond_to?সর্বজনীন পদ্ধতির জন্য সত্য ফিরে আসবে, ক্লাসে "পদ্ধতির সংজ্ঞা" পরীক্ষা করা ব্যক্তিগত পদ্ধতির সাথে সম্পর্কিতও হতে পারে।

রুবি ভি ২.০-তে সরকারী ও বেসরকারী উভয় সেট চেক করেই অর্জন করা যায়

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