রুবি alচ্ছিক পরামিতি


121

যদি আমি এইভাবে কোনও রুবি ফাংশন সংজ্ঞায়িত করি:

def ldap_get ( base_dn, filter, scope=LDAP::LDAP_SCOPE_SUBTREE, attrs=nil )

আমি কীভাবে এটি কেবল প্রথম 2 এবং শেষ আরগগুলি সরবরাহ করতে পারি? কেন এমন কিছু হয় না

ldap_get( base_dn, filter, , X)

সম্ভব বা যদি সম্ভব হয় তবে কীভাবে এটি করা যায়?

উত্তর:


131

রুবি দিয়ে বর্তমানে এটি সম্ভব নয়। আপনি পদ্ধতিগুলিতে 'খালি' বৈশিষ্ট্যগুলি পাস করতে পারবেন না। নিকটতম পাস আপনি পেতে পারেন:

ldap_get(base_dn, filter, nil, X)

তবে এটি এলডিপ :: এলডিএপ :: এলডিএপি :: এলডিপিকে নয়, এই সুযোগটি নির্ধারণ করবে n

আপনি যা করতে পারেন তা হল আপনার পদ্ধতির মধ্যে ডিফল্ট মান সেট করা:

def ldap_get(base_dn, filter, scope = nil, attrs = nil)
  scope ||= LDAP::LDAP_SCOPE_SUBTREE
  ... do something ...
end

এখন আপনি যদি পদ্ধতিটিকে উপরে হিসাবে কল করেন তবে আচরণটি আপনার প্রত্যাশার মতো হবে।


21
এই পদ্ধতিতে একটু gotcha হয়: যেমন আপনার জন্য ডিফল্ট মান করতে চেষ্টা যদি করছি scopeসত্য এবং আপনি মধ্যে পাস false, scope ||= trueকাজ হবে না। এটি একই হিসাবে মূল্যায়ন করে nilএবং এটিতে সেট করবেtrue
জোশুয়া পিন্টার

4
এই উত্তরের 3 বছর পরে রুবির বর্তমান সংস্করণটি দিয়ে কি সম্ভব?
ডালোলিওগম

1
@ জোশপিন্টার, সুন্দর ব্যাখ্যা। মূলত || = এ = বি বা সি নয়, আমি দেখে ক্রিঙ্কড হয়েছি xyz||=true। এটি যদি শূন্য হয় তবে তা সবসময় সত্য। যদি এটি সত্য হয় তবে এটি সত্য।
দামন আও

7
সবাই যে কত খারাপ scope ||= trueতা বলার সাথে সাথে আমি অবাক হয়েছি যে এটি করার সর্বোত্তম উপায়টি কেউই উল্লেখ করেনি scope = LDAP::LDAP_SCOPE_SUBTREE if scope.nil?। অবশ্যই, এমনকি এটি ধরে নিচ্ছে যে nilএটি একটি অবৈধ মান।
এরিক স্যান্ডবার্গ

1
এই বয়স্ককে আপডেট করুন: একটি বিকল্প হ'ল আন্ডারস্কোর স্বরলিপি ব্যবহার করা। দুর্ভাগ্যক্রমে, এটি পরামিতি সেট করার মতো একই প্রভাব ফেলে nil। কিছু স্বরলিপিটি পছন্দ করতে পারে: ldap_get(base_dn, filter, _, X)(দ্রষ্টব্য: রুবিতে এটি কখন চালু হয়েছিল আমি জানি না (এখনও) ing আকর্ষণীয় এসও থ্রেড )।
এরিক প্লাটন

137

অপশন হ্যাশ ব্যবহার করে আপনি প্রায় সর্বদা ভাল।

def ldap_get(base_dn, filter, options = {})
  options[:scope] ||= LDAP::LDAP_SCOPE_SUBTREE
  ...
end

ldap_get(base_dn, filter, :attrs => X)

23
একটি সাধারণ কৌশল হ'ল একটি ডিফল্ট বিকল্প হ্যাশ থাকে এবং যা যা পাস হয়েছিল তাতে মার্জ করে:options = default_options.merge(options)
নাথান লং

7
আমি এটিকে নিরুৎসাহিত করি কারণ বিকল্পগুলি পদ্ধতিটি কী প্রত্যাশা করে বা ডিফল্ট মানগুলি কী তা আপনাকে বলে না
ব্রোন ডেভিস

53

সংস্করণ 2 রুবি নামের প্যারামিটার সমর্থন করে এবং সময় চলে গেছে:

def ldap_get ( base_dn, filter, scope: "some_scope", attrs: nil )
  p attrs
end

ldap_get("first_arg", "second_arg", attrs: "attr1, attr2") # => "attr1, attr2"

1
অতিরিক্ত সংজ্ঞায়িত কীওয়ার্ড আর্গুমেন্ট সংগ্রহ করতে আপনি একটি ডাবল স্প্ল্যাট ব্যবহার করতে পারেন। এটি এই ইস্যুটির সাথে সম্পর্কিত: স্ট্যাকওভারফ্লো.com
হেনরি

3

আপনি যেভাবে সংজ্ঞায়িত করেছেন এটি করা সম্ভব নয় ldap_get। তবে আপনি যদি এটির ldap_getমতো সংজ্ঞা দেন :

def ldap_get ( base_dn, filter, attrs=nil, scope=LDAP::LDAP_SCOPE_SUBTREE )

এখন তুমি পার:

ldap_get( base_dn, filter, X )

তবে এখন আপনার সমস্যা আছে যে আপনি এটিকে প্রথম দুটি আরগ এবং শেষ আরগ দিয়ে কল করতে পারবেন না (আগের মতো একই সমস্যা তবে এখন শেষ আরগটি আলাদা)

এর পক্ষে যুক্তিটি সহজ: রুবিতে প্রতিটি যুক্তির একটি ডিফল্ট মান থাকা প্রয়োজন না, তাই আপনি এটি নির্দিষ্ট করে বলতে পারেন না। আপনার ক্ষেত্রে, উদাহরণস্বরূপ, প্রথম দুটি আর্গুমেন্টের ডিফল্ট মান নেই।


1

1) আপনি পদ্ধতিটি ওভারলোড করতে পারবেন না ( কেন রুবি সাপোর্ট মেথড ওভারলোডিং হয় না? ) সুতরাং কেন সম্পূর্ণ নতুন পদ্ধতি লিখবেন না?

2) আমি শূন্য বা তার বেশি দৈর্ঘ্যের অ্যারের জন্য স্প্ল্যাট অপারেটর * ব্যবহার করে একই ধরণের সমস্যা সমাধান করেছি। তারপরে, আমি যদি পারতে পারি এমন একটি প্যারামিটারটি পাস করতে চাই, তবে এটি অ্যারে হিসাবে ব্যাখ্যা করা হবে, তবে যদি আমি কোনও প্যারামিটার ছাড়াই পদ্ধতিটি কল করতে চাই তবে আমার কিছুই পাস করতে হবে না। দেখুন রুবি ভাষা প্রোগ্রামিং পৃষ্ঠাগুলি 186/187


0

সম্প্রতি আমি এর চারপাশে একটি উপায় খুঁজে পেয়েছি। অ্যারেতে উপাদান রাখতে বা বাতিল করতে আমি optionচ্ছিক প্যারামিটার দিয়ে অ্যারে শ্রেণিতে একটি পদ্ধতি তৈরি করতে চেয়েছিলাম।

আমি যেভাবে এটি সিমুলেট করেছিলাম তা হ'ল প্যারামিটার হিসাবে একটি অ্যারে পাস করে, এবং তারপরে সেই সূচকের মান শূন্য ছিল কি না তা পরীক্ষা করে।

class Array
  def ascii_to_text(params)
    param_len = params.length
    if param_len > 3 or param_len < 2 then raise "Invalid number of arguments #{param_len} for 2 || 3." end
    bottom  = params[0]
    top     = params[1]
    keep    = params[2]
    if keep.nil? == false
      if keep == 1
        self.map{|x| if x >= bottom and x <= top then x = x.chr else x = x.to_s end}
      else
        raise "Invalid option #{keep} at argument position 3 in #{p params}, must be 1 or nil"
      end
    else
      self.map{|x| if x >= bottom and x <= top then x = x.chr end}.compact
    end
  end
end

বিভিন্ন পরামিতি সহ আমাদের ক্লাস পদ্ধতিটি চেষ্টা করে দেখছি:

array = [1, 2, 97, 98, 99]
p array.ascii_to_text([32, 126, 1]) # Convert all ASCII values of 32-126 to their chr value otherwise keep it the same (That's what the optional 1 is for)

আউটপুট: ["1", "2", "a", "b", "c"]

ঠিক আছে, শীতল যে পরিকল্পনা হিসাবে কাজ করে। এখন আসুন পরীক্ষা করে দেখুন এবং দেখুন যদি আমরা অ্যারে তৃতীয় প্যারামিটার অপশন (1) এ পাস না করি তবে কী ঘটে।

array = [1, 2, 97, 98, 99]
p array.ascii_to_text([32, 126]) # Convert all ASCII values of 32-126 to their chr value else remove it (1 isn't a parameter option)

আউটপুট: ["a", "b", "c"]

আপনি দেখতে পাচ্ছেন, অ্যারেতে তৃতীয় বিকল্পটি সরিয়ে ফেলা হয়েছে, এভাবে পদ্ধতিতে একটি পৃথক বিভাগ শুরু করা এবং আমাদের পরিসীমাতে নয় এমন সমস্ত ASCII মানগুলি অপসারণ করা (32-126)

বিকল্পভাবে, আমরা পরামিতিগুলিতে শূন্য হিসাবে মান ইস্যু করতে পারতাম। যা নিম্নলিখিত কোড ব্লকের অনুরূপ দেখাবে:

def ascii_to_text(top, bottom, keep = nil)
  if keep.nil?
    self.map{|x| if x >= bottom and x <= top then x = x.chr end}.compact
  else
    self.map{|x| if x >= bottom and x <= top then x = x.chr else x = x.to_s end}
end

-1

এটা সম্ভব :) শুধু সংজ্ঞা পরিবর্তন করুন

def ldap_get ( base_dn, filter, scope=LDAP::LDAP_SCOPE_SUBTREE, attrs=nil )

প্রতি

def ldap_get ( base_dn, filter, *param_array, attrs=nil )
scope = param_array.first || LDAP::LDAP_SCOPE_SUBTREE

সুযোগটি এখন তার প্রথম স্থানে অ্যারেতে থাকবে। আপনি যখন 3 টি আর্গুমেন্ট সরবরাহ করেন, তারপরে আপনি বেস_ডএন নির্ধারণ করবেন, ফিল্টার এবং অ্যাটর্স এবং পরম_আরে হবে [] যখন 4 এবং আরও বেশি আর্গুমেন্ট হয় তখন পরম_আরে হবে [যুক্তি 1, বা_মোর, এবং_মোর]

ডাউনসাইড হ'ল ... এটি অস্পষ্ট সমাধান, সত্যিই কুৎসিত। এটির জবাব দেওয়া যায় যে রুবিতে ফাংশন কলের মাঝখানে যুক্তি বাদ দেওয়া সম্ভব হবে :)

আপনার আর একটি জিনিস যা করতে হবে তা হ'ল সুযোগের ডিফল্ট মানটি আবার লিখতে।


4
এই সমাধানগুলি সম্পূর্ণ ভুল। এটি attrs=nilএকটি স্প্ল্যাটের ( *param_array) পরে ডিফল্ট মান প্যারামিটার ( ) ব্যবহার করা একটি সিনট্যাক্স ত্রুটি ।
এরিক স্যান্ডবার্গ

3
-১: এরিক সঠিক। আইআরবি 2.0.0p247 এ একটি সিনট্যাক্স ত্রুটি ঘটায়। রুবি প্রোগ্রামিং ল্যাঙ্গুয়েজের মতে , রুবি ১.৮-তে স্প্ল্যাট প্যারামিটারটি একটি ব্যতীত শেষ হওয়া উচিত ছিল &parameter, তবে রুবি ১.৯ এ এটি "সাধারণ পরামিতি" দ্বারা অনুসরণ করা যেতে পারে। উভয় ক্ষেত্রেই স্প্ল্যাটের সাথে প্যারামিটারের পরে কোনও ডিফল্ট আইনী পরামিতি ছিল না।
andyg0808

রুবি প্রোগ্রামিং ল্যাঙ্গুয়েজ পৃষ্ঠা 186/187 স্প্ল্যাট পদ্ধতিগুলির সাথে ব্যবহার করা ভাল। এটি ব্যবহার না করা অবধি পদ্ধতিতে সর্বশেষ পরামিতি হতে হবে।
rupweb

সুতরাং অ্যান্ডি ঠিক আছে, অর্ডারটি হওয়া দরকার: Def ldap_get (বেস_ডএন, ফিল্টার, অ্যাট্রেস = শূন্য, * পরম_আরে)
রুপউইব

-1

আপনি আংশিক প্রয়োগের মাধ্যমে এটি করতে পারেন, যদিও নামযুক্ত ভেরিয়েবলগুলি নিশ্চিতভাবে আরও পঠনযোগ্য কোডের দিকে নিয়ে যায়। জন রেসিগ জাভাস্ক্রিপ্টে এটি কীভাবে করবেন সে সম্পর্কে ২০০৮ সালে একটি ব্লগ নিবন্ধ লিখেছিলেন: http://ejohn.org/blog/partial-funitions-in-javascript/

Function.prototype.partial = function(){
  var fn = this, args = Array.prototype.slice.call(arguments);
  return function(){
    var arg = 0;
    for ( var i = 0; i < args.length && arg < arguments.length; i++ )
      if ( args[i] === undefined )
        args[i] = arguments[arg++];
    return fn.apply(this, args);
  };
};

সম্ভবত রুবিতে একই নীতি প্রয়োগ করা সম্ভব হবে (প্রোটোটাইপাল উত্তরাধিকার বাদে)।

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