سؤال

شيء واحد أنا أحب حول روبي هو أن الغالب هو للقراءة اللغة (وهو أمر عظيم بالنسبة الذاتي توثيق رمز)

ومع ذلك ، مستوحاة من هذا السؤال: روبي البرمجية شرح ووصف كيف ||= يعمل في روبي ، كنت أفكر روبي التعابير لا تستخدم ، بصراحة أنا لا تماما جروك لهم.

لذلك سؤالي هو تشبه المثال من الرجوع إليها السؤال ، ما شيوعا ، ولكن ليس واضحا ، روبي التعابير هل أنا بحاجة إلى أن يكون على بينة من أن يكون حقا يتقن روبي مبرمج ؟

بالمناسبة من الإشارة السؤال

a ||= b 

ما يعادل

if a == nil || a == false
  a = b
end

(شكرا إلى إيان تيريل للتصحيح)

تحرير: اتضح أن هذه النقطة ليست تماما جدال.الصحيح التوسع في الواقع

(a || (a = (b))) 

انظر هذه الروابط لماذا:

بفضل يورغ W Mittag عن الإشارة إلى هذا.

هل كانت مفيدة؟

المحلول

جملة if السحرية التي تتيح لنفس الملف العمل كمكتبة أو برنامج نصي:

if __FILE__ == $0
  # this library may be run as a standalone script
end

تعبئة وتفريغ المصفوفات:

# put the first two words in a and b and the rest in arr
a,b,*arr = *%w{a dog was following me, but then he decided to chase bob}
# this holds for method definitions to
def catall(first, *rest)
  rest.map { |word| first + word }
end
catall( 'franken', 'stein', 'berry', 'sense' ) #=> [ 'frankenstein', 'frankenberry', 'frankensense' ]

السكر النحوي للتجزئات كوسيطات للأسلوب

this(:is => :the, :same => :as)
this({:is => :the, :same => :as})

مُهيئات التجزئة:

# this
animals = Hash.new { [] }
animals[:dogs] << :Scooby
animals[:dogs] << :Scrappy
animals[:dogs] << :DynoMutt
animals[:squirrels] << :Rocket
animals[:squirrels] << :Secret
animals #=> {}
# is not the same as this
animals = Hash.new { |_animals, type| _animals[type] = [] }
animals[:dogs] << :Scooby
animals[:dogs] << :Scrappy
animals[:dogs] << :DynoMutt
animals[:squirrels] << :Rocket
animals[:squirrels] << :Secret
animals #=> {:squirrels=>[:Rocket, :Secret], :dogs=>[:Scooby, :Scrappy, :DynoMutt]}

بناء جملة metaclass

x = Array.new
y = Array.new
class << x
  # this acts like a class definition, but only applies to x
  def custom_method
     :pow
  end
end
x.custom_method #=> :pow
y.custom_method # raises NoMethodError

متغيرات مثيل الفئة

class Ticket
  @remaining = 3
  def self.new
    if @remaining > 0
      @remaining -= 1
      super
    else
      "IOU"
    end
  end
end
Ticket.new #=> Ticket
Ticket.new #=> Ticket
Ticket.new #=> Ticket
Ticket.new #=> "IOU"

الكتل، procs، و lambdas.عيشهم وتنفسهم.

 # know how to pack them into an object
 block = lambda { |e| puts e }
 # unpack them for a method
 %w{ and then what? }.each(&block)
 # create them as needed
 %w{ I saw a ghost! }.each { |w| puts w.upcase }
 # and from the method side, how to call them
 def ok
   yield :ok
 end
 # or pack them into a block to give to someone else
 def ok_dokey_ok(&block)
    ok(&block)
    block[:dokey] # same as block.call(:dokey)
    ok(&block)
 end
 # know where the parentheses go when a method takes arguments and a block.
 %w{ a bunch of words }.inject(0) { |size,w| size + 1 } #=> 4
 pusher = lambda { |array, word| array.unshift(word) }
 %w{ eat more fish }.inject([], &pusher) #=> ['fish', 'more', 'eat' ]

نصائح أخرى

هذا عرض الشرائح مكتمل تمامًا في مصطلحات روبي الرئيسية، كما في:

  • مبادلة قيمتين:

    x, y = y, x

  • المعلمات التي، إذا لم يتم تحديدها، تأخذ بعض القيمة الافتراضية

    def somemethod(x, y=nil)

  • يجمع المعلمات الدخيلة في مصفوفة

    def substitute(re, str, *rest)

وما إلى ذلك وهلم جرا...

المزيد من العبارات الاصطلاحية:

استخدام %w, %r و %( المحددات

%w{ An array of strings %}
%r{ ^http:// }
%{ I don't care if the string has 'single' or "double" strings }

مقارنة النوع في بيانات الحالة

def something(x)
  case x
    when Array
      # Do something with array
    when String
      # Do something with string
    else
      # You should really teach your objects how to 'quack', don't you?
  end
end

...والإساءة الشاملة لل === الطريقة في بيانات الحالة

case x
  when 'something concrete' then ...
  when SomeClass then ...
  when /matches this/ then ...
  when (10...20) then ...
  when some_condition >= some_value then ...
  else ...
end

شيء ينبغي أن يبدو طبيعيًا بالنسبة للروبيين، ولكن ربما ليس كذلك بالنسبة للأشخاص القادمين من لغات أخرى:استخدام each لصالح for .. in

some_iterable_object.each{|item| ... }

في الإصدار Ruby 1.9+، أو Rails، أو عن طريق تصحيح طريقة الرمز #to_proc، هذا أصبح مصطلحًا شائعًا بشكل متزايد:

strings.map(&:upcase)

الطريقة الشرطية/التعريف الثابت

SOME_CONSTANT = "value" unless defined?(SOME_CONSTANT)

أساليب الاستعلام والأساليب التدميرية (الانفجار).

def is_awesome?
  # Return some state of the object, usually a boolean
end

def make_awesome!
  # Modify the state of the object
end

المعلمات الضجة الضمنية

[[1, 2], [3, 4], [5, 6]].each{ |first, second| puts "(#{first}, #{second})" }

أحب هذا:

str = "Something evil this way comes!"
regexp = /(\w[aeiou])/

str[regexp, 1] # <- This

وهو ما يعادل (تقريبًا) ما يلي:

str_match = str.match(regexp)
str_match[1] unless str_match.nil?

أو على الأقل هذا ما استخدمته لاستبدال هذه الكتل.

أود أن أقترح قراءة كود المكونات الإضافية أو الأحجار الكريمة المشهورة والمصممة بشكل جيد من الأشخاص الذين تعجبهم وتحترمهم.

بعض الأمثلة التي واجهتها:

if params[:controller] == 'discussions' or params[:controller] == 'account'
  # do something here
end

المقابلة ل

if ['account', 'discussions'].include? params[:controller]
  # do something here
end

والتي سيتم إعادة هيكلتها لاحقًا

if ALLOWED_CONTROLLERS.include? params[:controller]
  # do something here
end

إليك بعض منها، منقولة من مصادر مختلفة:

استخدم "ما لم" و"حتى" بدلاً من "إذا لم يكن" و"في حين لا".حاول ألا تستخدم "ما لم" عند وجود شرط "آخر".

تذكر أنه يمكنك تعيين متغيرات متعددة في وقت واحد:

a,b,c = 1,2,3

وحتى تبديل المتغير بدون درجة حرارة:

a,b = b,a

استخدم الشروط الشرطية الزائدة عند الاقتضاء، على سبيل المثال.

do_something_interesting unless want_to_be_bored?

كن على دراية بالطريقة شائعة الاستخدام ولكنها ليست واضحة على الفور (بالنسبة لي على الأقل) لتحديد أساليب الفصل:

class Animal
  class<<self
    def class_method
      puts "call me using Animal.class_method"
    end
  end
end

بعض المراجع:

بالمناسبة من الرجوع إليها السؤال

a ||= b 

ما يعادل

if a == nil   
  a = b 
end

هذا بمهارة غير صحيحة ، و هو مصدر الخلل في القادمين الجدد' روبي التطبيقات.

لأن كلا (فقط) nil و false تقييم منطقية كاذبة ، a ||= b هو في الواقع (تقريبا*) أي ما يعادل:

if a == nil || a == false
  a = b
end

أو إعادة كتابتها مع آخر روبي لغة:

a = b unless a

(*لأن كل بيان له قيمة ، هذه ليست من الناحية الفنية ما يعادل a ||= b.ولكن إذا كنت لا تعتمد على قيمة البيان بأنك لن ترى فرقا.)

أحتفظ بصفحة ويكي تغطي بعض مصطلحات وتنسيقات روبي:

https://github.com/tokland/tokland/wiki/RubyIdioms

أنسى دائمًا بناء الجملة الدقيق لهذا الاختصار إذا كان عبارة else (واسم عامل التشغيل.تعليقات أي شخص؟) أعتقد أنه يستخدم على نطاق واسع خارج روبي، ولكن في حالة أراد شخص آخر بناء الجملة هنا فهو:

refactor < 3 ? puts("No need to refactor YET") : puts("You need to refactor this into a  method")

يتسع ل

if refactor < 3
  puts("No need to refactor YET")
else
  puts("You need to refactor this into a  method")
end

تحديث

يسمى المشغل الثلاثي:

عودة مايفار ؟حجم myvar :0

يمكنك deepcopy مع تنظيم كائن بسهولة.- مأخوذة من لغة البرمجة روبي

def deepcopy(o)
  Marshal.load(Marshal.dump(o))
end

لاحظ أن الملفات I/O تيارات ، فضلا عن طريقة الربط الكائنات ، هي حيوية جدا أن يكون تنظيم;هناك لن تكون هناك طريقة يمكن الاعتماد عليها لاستعادة دولتهم.

a = (b && b.attribute) || "default"

تقريبًا:

if ( ! b.nil? && ! b == false) && ( ! b.attribute.nil? && ! b.attribute.false) a = b
else a = "default"

أستخدم هذا عندما يكون b عبارة عن سجل ربما تم العثور عليه أو لم يتم العثور عليه، وأحتاج إلى الحصول على إحدى سماته.

تعجبني الطريقة التي يمكن بها اختصار If-then-elses أو case-when لأنها تُرجع قيمة:

if test>0
  result = "positive"
elsif test==0
  result = "zero"
else
  result = "negative"
end

يمكن إعادة كتابتها

result = if test>0
  "positive"
elsif test==0
  "zero"
else
  "negative"
end

ويمكن تطبيق الشيء نفسه على الحالة عندما:

result = case test
when test>0 ; "positive"
when test==0 ; "zero"
else "negative"
end

Array.pack وString.unpack للعمل مع الملفات الثنائية:

# extracts four binary sint32s to four Integers in an Array
data.unpack("iiii") 

طريقة السحر المفقود

class Dummy  
  def method_missing(m, *args, &block)  
    "You just called method with name #{m} and arguments- #{args}"  
  end  
end

Dummy.new.anything(10, 20)
=> "You just called method with name anything and arguments- [10, 20]"

إذا قمت باستدعاء أساليب غير موجودة في كائنات روبي، فسوف يستدعي مترجم روبي الأسلوب المسمى "method_missing" إذا تم تعريفه، فيمكنك استخدامه لبعض الحيل، مثل كتابة أغلفة API، أو DSL، حيث لا تعرف جميع الأساليب والمعلمات أسماء

سؤال جيد!

أعتقد أنه كلما كان الكود أكثر سهولة وسرعة، كلما كان البرنامج الذي نبنيه أفضل.سأوضح لك كيف أعبر عن أفكاري باستخدام روبي في مقتطفات صغيرة من التعليمات البرمجية. اقرأ المزيد هنا

خريطة

يمكننا استخدام طريقة الخريطة بطرق مختلفة:

user_ids = users.map { |user| user.id }

أو:

user_ids = users.map(&:id)

عينة

يمكننا استخدام طريقة راند:

[1, 2, 3][rand(3)]

خلط:

[1, 2, 3].shuffle.first

والطريقة الاصطلاحية والبسيطة والأسهل..عينة!

[1, 2, 3].sample

الأنابيب المزدوجة يساوي / الحفظ

كما قلت في الوصف، يمكننا استخدام الحفظ:

some_variable ||= 10
puts some_variable # => 10

some_variable ||= 99
puts some_variable # => 10

الطريقة الثابتة / طريقة الفصل

أحب استخدام أساليب الفصل، وأشعر أنها طريقة اصطلاحية لإنشاء الفصول واستخدامها:

GetSearchResult.call(params)

بسيط.جميل.حدسي.ماذا يحدث في الخلفية؟

class GetSearchResult
  def self.call(params)
    new(params).call
  end

  def initialize(params)
    @params = params
  end

  def call
    # ... your code here ...
  end
end

لمزيد من المعلومات حول كيفية كتابة رمز روبي الاصطلاحي، اقرأ هنا

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top