মডিউলগুলিতে নেস্টেড ক্লাস এবং ক্লাসগুলি কখন ব্যবহার করবেন?


144

আমি সাবক্ল্যাস এবং মডিউলগুলি কখন ব্যবহার করব সে সম্পর্কে আমি বেশ পরিচিত, তবে খুব সম্প্রতি আমি নেস্টেড ক্লাসগুলি এইরকম দেখছি:

class Foo
  class Bar
    # do some useful things
  end
end

পাশাপাশি ক্লাসগুলি যেমন মডিউলগুলিতে নেস্টেড থাকে:

module Baz
  class Quux
    # more code
  end
end

হয় ডকুমেন্টেশন এবং নিবন্ধগুলি অপ্রয়োজনীয় বা সঠিক বিষয়ে অনুসন্ধানের জন্য আমি পর্যাপ্ত শিক্ষিত নই, তবে আমি এই বিষয়ে খুব বেশি তথ্য সন্ধান করতে পারি না।

কেউ কেন পোস্টিংগুলিতে উদাহরণগুলি বা লিঙ্ক সরবরাহ করতে পারে / কখন সেই কৌশলগুলি ব্যবহার করা হবে?

উত্তর:


140

অন্যান্য ওওপি ভাষার অভ্যন্তর শ্রেণি রয়েছে যা উচ্চ স্তরের শ্রেণিতে আবদ্ধ না হয়ে তাত্ক্ষণিকভাবে চলতে পারে না। উদাহরণস্বরূপ, জাভাতে,

class Car {
    class Wheel { }
}

Carক্লাসে শুধুমাত্র পদ্ধতিগুলি Wheelএস তৈরি করতে পারে ।

রুবির এমন আচরণ নেই।

রুবিতে,

class Car
  class Wheel
  end
end

থেকে পৃথক

class Car
end

class Wheel
end

শুধুমাত্র ক্লাসের নামে Wheelবনাম Car::Wheel। নামের এই পার্থক্যটি প্রোগ্রামারদের কাছে স্পষ্ট করে তুলতে পারে যে Car::Wheelক্লাসটি একটি সাধারণ চক্রের বিপরীতে কেবল একটি গাড়ির চক্রকেই উপস্থাপন করতে পারে। রুবীতে বাসা বাঁধার শ্রেণি সংজ্ঞাটি পছন্দের বিষয়, তবে এটি এই উদ্দেশ্যে একটি উদ্দেশ্য পরিবেশন করে যে এটি দুটি শ্রেণীর মধ্যে একটি চুক্তি আরও দৃ strongly়তার সাথে কার্যকর করে এবং এটি করার ফলে তাদের এবং তাদের ব্যবহার সম্পর্কে আরও তথ্য সরবরাহ করে।

তবে রুবি ইন্টারপ্রেটারের কাছে এটি নামের মধ্যে কেবল একটি পার্থক্য।

আপনার দ্বিতীয় পর্যবেক্ষণ হিসাবে, মডিউলগুলির ভিতরে বাসা বাঁধার ক্লাসগুলি সাধারণত ক্লাসের নাম স্থানটিতে ব্যবহৃত হয়। এই ক্ষেত্রে:

module ActiveRecord
  class Base
  end
end

থেকে পৃথক

module ActionMailer
  class Base
  end
end

যদিও এটি মডিউলগুলির ভিতরে বাসা বাঁধতে পারে এমন ক্লাসগুলির একমাত্র ব্যবহার নয়, এটি সাধারণত সবচেয়ে সাধারণ।


5
@ রবিপ্রিন্স, আমি নিশ্চিত নই যে আপনি Car.newএবং এর মধ্যে সম্পর্ক স্থাপনের মাধ্যমে কী বোঝাতে চাইছেন Car::Wheel.new। রুবিতে অবজেক্টটি Carআরম্ভ করার জন্য আপনাকে অবশ্যই কোনও অবজেক্টটি আরম্ভ করার দরকার নেই Car::Wheel, তবে ব্যবহারযোগ্য হওয়ার Carজন্য ক্লাসটি লোড এবং সম্পাদন Car::Wheelকরতে হবে।
পান থোমাকোস

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

7
আমার কী ধারণা নেই যে এই উত্তরটি কীভাবে 60 টি আপত্তি পেয়েছে, একা একা ওপি কর্তৃক গৃহীত হয়েছিল। আক্ষরিকভাবে এখানে একটি সত্য বিবৃতি নেই। রুবিতে বিটা বা নিউজসিয়াকের মতো নেস্টেড ক্লাস নেই। Carএবং এর মধ্যে যে কোনও সম্পর্ক নেই Car::Wheel। মডিউলগুলি (এবং এইভাবে ক্লাসগুলি) কেবল ধ্রুবকদের জন্য নেমস্পেসস, রুবিতে নেস্টেড বর্গ বা নেস্টেড মডিউল বলে কোনও জিনিস নেই।
Jörg ডব্লু মিটাগ

4
উভয়ের মধ্যে কেবলমাত্র পার্থক্য হ'ল ধ্রুবক রেজোলিউশন (যা সংক্ষিপ্ত, এবং এইভাবে স্পষ্টতই পৃথক কারণ দুটি স্নিপেট লেক্সিকালি পৃথক)। জড়িত ক্লাস সম্পর্কে উভয়ের মধ্যে অবশ্য কোনও পার্থক্য নেই। কেবল দুটি সম্পূর্ণ অপ্রাসঙ্গিক শ্রেণি রয়েছে। সময়কাল। রুবির নেস্টেড / ইনার ক্লাস নেই। নেস্টেড ক্লাস তোমার সংজ্ঞা সঠিক, কিন্তু এটা কেবল রুবি প্রযোজ্য নয় হিসাবে আপনি জাভাস্ক্রিপ্টে গার্বেজ পরীক্ষা করতে পারেন: Car::Wheel.new। গম্ভীর গর্জন। আমি সবেমাত্র একটি Wheelঅবজেক্ট তৈরি করেছি যা কোনও Carবস্তুর অভ্যন্তরে বাসা বাঁধে না ।
Jörg ডব্লু মিটাগ

10
সম্পূর্ণ মন্তব্য থ্রেড না পড়ে এই পোস্টটি অত্যন্ত বিভ্রান্তিকর।
নাথান

50

রুবিতে, নেস্টেড ক্লাসটি সংজ্ঞায়িত করা মডিউলটিতে শ্রেণি সংজ্ঞায়িত করার অনুরূপ। এটি আসলে ক্লাসগুলির মধ্যে কোনও সম্পর্ককে জোর করে না, এটি কেবল ধ্রুবকদের জন্য একটি নামস্থান তৈরি করে। (ক্লাস এবং মডিউলের নামগুলি ধ্রুবক))

গৃহীত উত্তর কোনও কিছুর বিষয়ে সঠিক ছিল না। 1 নীচের উদাহরণে আমি নিবিড়ভাবে বদ্ধ শ্রেণীর একটি উদাহরণ তৈরি করি যেখানে উপস্থিত বদ্ধ ক্লাসের উদাহরণ নেই।

class A; class B; end; end
A::B.new

মডিউলগুলির জন্য সুবিধাগুলি হ'ল: এনক্যাপসুলেশন, কেবলমাত্র এক জায়গায় গ্রুপিং কোড ব্যবহার করা হয় এবং কোডটি যেখানে ব্যবহৃত হয় তার কাছাকাছি রেখে দেয়। একটি বৃহত প্রকল্পের একটি বহিরাগত মডিউল থাকতে পারে যা প্রতিটি উত্স ফাইলে বারবার ঘটে এবং এতে অনেকগুলি সংজ্ঞাগুলি থাকে। বিভিন্ন ফ্রেমওয়ার্ক এবং গ্রন্থাগার কোডগুলি যখন এগুলি করে, তখন তারা দ্বন্দ্বের সম্ভাবনা হ্রাস করে শীর্ষ স্তরে প্রতিটি করে একটি নাম অবদান রাখে। প্রসাইক, নিশ্চিত হওয়ার জন্য, তবে সেগুলি ব্যবহার করা হয়।

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

আপনি এমনকি স্ক্রিপ্টগুলির জন্য সাধারণ প্যাটার্নটি ব্যবহার করতে পারেন, যেখানে কেবল মজাদার এবং অনুশীলনের জন্য নেমস্পেসের ভয়ঙ্কর প্রয়োজন হয় না ...

#!/usr/bin/env ruby

class A
  class Realwork_A
    ...
  end
  class Realwork_B
    ...
  end

  def run
    ...
  end

  self
end.new.run

15
দয়া করে, দয়া করে, দয়া করে একে অভ্যন্তর শ্রেণি বলবেন না। এটা না। বর্গ Bহয় না ভিতরে বর্গ Aধ্রুব B ভিতরে বর্গ namespaced হয় A, কিন্তু সেখানে একেবারে বস্তু দ্বারা রেফারেন্সড মধ্যে কোন সম্পর্ক নেই B(যা এই ক্ষেত্রে শুধু একটি বর্গ হতে হবে) এবং ক্লাস দ্বারা সমর্থিত A
Jörg ডব্লু মিটাগ

2
ঠিক আছে, "অভ্যন্তরীণ" পরিভাষা সরানো হয়েছে। ভাল যুক্তি. যারা উপরোক্ত তর্কটি অনুসরণ করছেন না তাদের পক্ষে এই বিবাদের কারণটি হ'ল আপনি যখন এই জাতীয় কিছু করেন, জাভাটি বলুন, অভ্যন্তরীণ শ্রেণীর অবজেক্টগুলি (এবং এখানে আমি স্বতন্ত্র শব্দটি ব্যবহার করছি) এতে একটি উল্লেখ রয়েছে contain বাইরের শ্রেণি এবং বাহ্যিক উদাহরণের ভেরিয়েবলগুলি অভ্যন্তরীণ শ্রেণীর পদ্ধতি দ্বারা উল্লেখ করা যেতে পারে can আপনি কোডের সাথে লিঙ্ক না করলে রুবিতে এর কিছুই হয় না। এবং আপনি কি জানেন যে যদি কোডটি অহেম, এনক্লোজিং ক্লাসে উপস্থিত থাকত তবে আমি বাজি ধরতে পারি যে আপনি যুক্তিসঙ্গতভাবে বারটিকে একটি অভ্যন্তর শ্রেণি বলতে পারেন।
ডিজিটালরোস 10'15

1
আমার কাছে এটি এই বিবৃতিটি যা মডিউল এবং শ্রেণীর মধ্যে সিদ্ধান্ত নেওয়ার সময় আমাকে সবচেয়ে বেশি সহায়তা করে: You can't call new on a module.- তাই যদি আমি কেবল কিছু শ্রেণির নাম স্পেস করতে চাই এবং বাস্তবে কখনই বাইরের "শ্রেণি" এর উদাহরণ তৈরি করার প্রয়োজন না হয় , তবে আমি একটি বাহ্যিক মডিউল ব্যবহার করব। তবে যদি আমি মোড়ানো / বহিরাগত "শ্রেণি" এর কোনও উদাহরণ ইনস্ট্যান্ট করতে চাই তবে আমি এটিকে মডিউলের পরিবর্তে একটি শ্রেণি হিসাবে তৈরি করব। কমপক্ষে এটি আমার কাছে বোধগম্য হয়।
ফায়ারড্রাগন

@ ফায়ারড্রাগন বা অন্য কোনও ব্যবহারের ক্ষেত্রে হতে পারে আপনি এমন একটি ক্লাস চান যা একটি কারখানা, যা সাবক্লাসের উত্তরাধিকার সূত্রে প্রাপ্ত এবং আপনার কারখানাটি সাবক্লাসগুলির উদাহরণ তৈরি করার জন্য দায়ী। সেই পরিস্থিতিতে আপনার কারখানাটি মডিউল হতে পারে না কারণ আপনি মডিউলটি থেকে উত্তরাধিকারী হতে পারবেন না, সুতরাং এটি এমন একটি পিতামাতার শ্রেণি যা আপনি ইনস্ট্যান্ট করেন না (এবং যদি চান তবে এটি শিশুদের 'নেমস্পেস' করতে পারেন),
একধরণের

15

আপনি সম্ভবত এই ব্যবহার করতে চান গ্রুপ একটি মডিউল আপনার ক্লাস। একটি নেমস্পেসের জিনিস বাছাই করুন।

উদাহরণস্বরূপ টুইটার মণি এটি অর্জনের জন্য নেমস্পেস ব্যবহার করে:

Twitter::Client.new

Twitter::Search.new

সুতরাং উভয় Clientএবং Searchশ্রেণি Twitterমডিউল অধীনে বাস ।

আপনি যদি সূত্রগুলি পরীক্ষা করতে চান তবে উভয় শ্রেণির জন্য কোডটি এখানে এবং এখানে পাওয়া যাবে

আশাকরি এটা সাহায্য করবে!


3
টুইটার মণি আপডেট লিংক: github.com/sferik/twitter/tree/master/lib/twitter
কোড

6

২.৫ এর আগে রুবীতে নেস্টেড ক্লাস এবং নেস্টেড মডিউলগুলির মধ্যে আরও একটি পার্থক্য রয়েছে যে অন্যান্য উত্তরগুলি আমার এখানে উল্লেখ করা আবশ্যক বলে আবরণ করতে ব্যর্থ হয়েছিল। এটি দেখার প্রক্রিয়া।

সংক্ষেপে: 2.5 এর আগে রুবিতে শীর্ষ স্তরের ধ্রুবক সন্ধানের কারণে রুবি আপনার নেস্টেড ক্লাসটি ভুল জায়গায় ( Objectবিশেষত) ভুল জায়গায় অনুসন্ধান করতে পারে।

রুবিতে 2.5 এর আগে:
নেস্টেড বর্গ কাঠামো: ধরুন আপনার একটি ক্লাস আছে X, নেস্টেড ক্লাস সহ Y, বা X::Y। এবং তারপরে আপনার একটি শীর্ষ স্তরের শ্রেণিও রয়েছে Y। যদি X::Yলোড করা হয়, তাহলে নিম্নলিখিত ঘটে যখন আপনি কল X::Y:

পাওয়া যায়নি রয়ে Yমধ্যে X, রুবি পূর্বপুরুষ মধ্যে কীভাবে এটি দেখার চেষ্টা করবে X। থেকেXএটি একটি শ্রেণি এবং মডিউল নয়, এর পূর্বসূর রয়েছে, যার মধ্যে রয়েছে [Object, Kernel, BasicObject]। সুতরাং, এটি জন্য সন্ধান করতে চেষ্টা করে Yযে Objectযেখানে এটা সফলভাবে খুঁজে বের করে।

তবুও এটি শীর্ষ স্তর Yএবং না X::Y। আপনি এই সতর্কতা পাবেন:

warning: toplevel constant Y referenced by X::Y


নেস্টেড মডিউল স্ট্রাকচার: ধরুন পূর্ববর্তী উদাহরণে Xএকটি মডিউল এবং কোনও শ্রেণি নয়।

একটি মডিউল কেবল পূর্বসূর হিসাবে নিজেকে থাকে: X.ancestorsউত্পাদন করবে [X]

এই ক্ষেত্রে, রুবি কোনও Yপূর্বপুরুষের মধ্যে সন্ধান করতে সক্ষম হবে না Xএবং একটি নিক্ষেপ করবে NameError। রেলগুলি (বা অটোলোডিং সহ অন্য কোনও ফ্রেমওয়ার্ক) এর X::Yপরে লোড করার চেষ্টা করবে ।

আরও তথ্যের জন্য এই নিবন্ধটি দেখুন: https://blog.jetbrains.com/ruby/2017/03/why-you-should-not-use-a-class-as-a-namespace-in-rails-applications/

ইন রুবি 2.5:
শীর্ষ স্তরের ধ্রুবক অনুসন্ধান সরানো হয়েছে।
আপনি এই বাগের মুখোমুখি হওয়ার ভয় ছাড়াই নেস্টেড ক্লাস ব্যবহার করতে পারেন।


3

পূর্ববর্তী উত্তরগুলি ছাড়াও: রুবিতে মডিউল একটি শ্রেণি

$ irb
> module Some end
=> nil
> Some.class
=> Module
> Module.superclass
=> Object

11
আপনি আরও সঠিক হতে চাইবেন যে 'রুবিতে ক্লাস একটি মডিউল'!
টিম ডিজিগিন্স

2
রুবির সমস্ত কিছু বস্তু হতে পারে তবে মডিউলটিকে একটি শ্রেণি কল করা সঠিক বলে মনে হচ্ছে না: << (মূল): 005: 0> Class.ancestors.reverse => [বেসিকঅবজেক্ট, কার্নেল, অবজেক্ট, মডিউল, শ্রেণি]
চাদ এম

এবং এখানে আমরা "হ'ল" এর
সংজ্ঞাটি পেয়েছি

নোট করুন যে মডিউলগুলি ইনস্ট্যান্ট করা যাবে না। অর্থাৎ মডিউল থেকে অবজেক্ট তৈরি করা সম্ভব নয়। সুতরাং মডিউলগুলি, ক্লাসগুলির বিপরীতে, কোনও পদ্ধতি নেইnew । সুতরাং যদিও আপনি মডিউলগুলি একটি শ্রেণি (ছোট হাতের অক্ষর) বলতে পারেন, তারা ক্লাস (বড় হাতের) হিসাবে একই জিনিস নয় :)
rmchaharry
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.