ฉันจะกลับก่อนได้อย่างไรจากภารกิจคราด?


226

ฉันมีงานเรคที่ฉันทำการตรวจสอบบางอย่างเมื่อเริ่มต้นหากการตรวจสอบอย่างใดอย่างหนึ่งล้มเหลวฉันต้องการกลับก่อนจากงานเรคฉันไม่ต้องการรันโค้ดใด ๆ ที่เหลืออยู่

ฉันคิดว่าวิธีแก้ปัญหาคือการวางคืนที่ฉันต้องการกลับจากรหัส แต่ฉันได้รับข้อผิดพลาดต่อไปนี้

unexpected return

คำตอบ:


285

ภารกิจคราดนั้นเป็นบล็อก บล็อกยกเว้น lambdas ไม่สนับสนุนการส่งคืน แต่คุณสามารถข้ามไปยังคำสั่งถัดไปโดยใช้nextในงานเรคซึ่งมีผลเหมือนกับการใช้การส่งคืนในเมธอด

task :foo do
  puts "printed"
  next
  puts "never printed"
end

หรือคุณสามารถย้ายรหัสในวิธีการและใช้กลับในวิธีการ

task :foo do
  do_something
end

def do_something
  puts "startd"
  return
  puts "end"
end

ฉันชอบตัวเลือกที่สอง


18
ฉันชอบคนที่สองที่ดีที่สุดเช่นกัน ยิ่งฉันใช้เรคมากเท่าไหร่ฉันก็ยิ่งชอบเก็บโค้ดที่ไม่สำคัญนอกนิยามงาน ไม่ใช่กฎที่มั่นคง 100% แต่ดูเหมือนจะเป็นแนวทางที่ดีในการทำงาน
Mike Woodhouse

6
ฉันได้ลองbreakแล้วและฉันพบข้อผิดพลาดนี้: rake ถูกยกเลิก! หยุดพักจากการปิด proc (ดูการติดตามแบบเต็มโดยใช้งานกับ --trace)
pupeno

4
ฉันชอบที่จะใช้ต่อไป ทำไมเราควรประกาศวิธีการใหม่เพื่อรองรับผลตอบแทนก่อน?
Derek Greer

5
คุณจะทำอย่างไรถ้าคุณซ้อนกันอย่างลึกล้ำในหลาย ๆ ช่วงตึก? ( nextใช้งานได้เฉพาะในกรณีที่มี "ระดับ" ของบล็อกที่จะแตกออก
mjs

3
คำเตือน: การประกาศเมธอดในภารกิจ Rake เป็นแนวคิดที่ไม่ดีเนื่องจากเป็นโกลบอลสำหรับงานเรคที่โหลดทั้งหมดซึ่งไม่เกี่ยวข้องกับเนมสเปซ ถัดไปถูกใช้แทนการหยุดพักเนื่องจากโค้ดในบล็อกอาจถูกเรียกหลายครั้งโดยสิ่งที่กำลังเรียกใช้บล็อก (คิดว่าวิธีการแต่ละ.)
Leslie Viljoen

181

คุณสามารถใช้abort(message)จากภายในงานเพื่อยกเลิกงานนั้นด้วยข้อความ


5
@TylerRick ไม่มีก็Kernel # ยกเลิก
Jo Liss

10
วิธีนี้ดีกว่าสำหรับการออกในสถานการณ์ที่ไม่ประสบความสำเร็จเนื่องจากตั้งสถานะการออกโดยอัตโนมัติ
samuil

นี่คือผู้ชนะ ยังเป็นวิธีที่ง่ายในการให้ข้อเสนอแนะการใช้งานสำหรับข้อผิดพลาดของการโต้แย้ง
David Hempy

Inline และอื่น ๆ nextอีกกว่าอธิบาย รักมัน
SomeSchmo

22

ฉันมักจะใช้abortซึ่งเป็นทางเลือกที่ดีกว่าในสถานการณ์เช่น:

task :foo do
  something = false
  abort 'Failed to proceed' unless something
end

1
แต่คุณจะabortออกโดยไม่ต้องใช้1รหัสทางออกได้อย่างไร งานเรคมักใช้ในบรรทัดคำสั่งเพื่อกำหนดความสำเร็จหรือความล้มเหลว มี "ความสำเร็จ" abortหรือไม่?
Joshua Pinter

2
ตอบคำถามของตัวเอง: ดูเหมือนว่าexitเป็นวิธีที่ดีในการออกจากที่ประสบความสำเร็จ
Joshua Pinter

19

กลับมาพร้อมกับข้อผิดพลาด❌

หากคุณกลับมาพร้อมกับข้อผิดพลาด (เช่นรหัสการออก1) คุณจะต้องการใช้abortซึ่งจะใช้พารามิเตอร์สตริงตัวเลือกที่จะได้รับผลลัพธ์เมื่อออก:

task :check do

  # If any of your checks fail, you can exit early like this.
  abort( "One of the checks has failed!" ) if check_failed?

end

บนบรรทัดคำสั่ง:

$ rake check && echo "All good"
#=> One of the checks has failed!

กลับมาพร้อมกับความสำเร็จ✅

หากคุณกลับมาโดยไม่มีข้อผิดพลาด (เช่นรหัสทางออก0) คุณจะต้องการใช้exitซึ่งจะไม่ใช้พารามิเตอร์สตริง

task :check do

  # If any of your checks fail, you can exit early like this.
  exit if check_failed?

end

บนบรรทัดคำสั่ง:

$ rake check && echo "All good"
#=> All good

นี่เป็นสิ่งสำคัญหากคุณกำลังใช้สิ่งนี้ในงาน cron หรือบางสิ่งที่จำเป็นต้องทำบางสิ่งในภายหลังโดยพิจารณาจากว่างาน rake นั้นสำเร็จหรือไม่


11

หากคุณจำเป็นต้องแยกออกจากหลายระดับบล็อกคุณสามารถใช้ล้มเหลว

ตัวอย่างเช่น

task :something do
  [1,2,3].each do |i|
    ...
    fail "some error" if ...
  end
end

(ดูhttps://stackoverflow.com/a/3753955/11543 )


8

หากคุณหมายถึงการออกจากภารกิจคราดโดยไม่ทำให้ "เรคถูกยกเลิก" ข้อความที่จะพิมพ์จากนั้นคุณสามารถใช้ "ยกเลิก" หรือ "ออก" แต่ "ยกเลิก" เมื่อใช้ในบล็อกช่วยเหลือให้ยกเลิกงานรวมทั้งพิมพ์ข้อผิดพลาดทั้งหมด (แม้จะไม่ใช้ --trace) ดังนั้น "ทางออก" คือสิ่งที่ฉันใช้


3
โดยทั่วไปแล้วผมคิดว่าการใช้ "ทางออก" แทนผลตอบแทน / แบ่งเป็นความคิดที่ไม่ดีเพราะมันไม่ได้เพียงแค่กระโดดออกมาจากในปัจจุบัน proc / วิธีการ / ฯลฯ - ออกจากกระบวนการทั้งหมดและข้ามรหัสใด ๆ ที่วิธีการโทรอาจตั้งใจจะรันหลังจากนั้น (รวมถึงการล้างข้อมูลบางส่วน) แต่สำหรับงานที่เสาะหาผมคิดว่ามันอาจจะไม่ได้เป็นปัญหา ...
ไทเลอร์ริก

0

ฉันใช้nextวิธีการที่ Simone Carletti แนะนำตั้งแต่เมื่อทำการทดสอบ rake abortซึ่งอันที่จริงเป็นเพียงเสื้อคลุมสำหรับexitไม่ใช่พฤติกรรมที่ต้องการ

ตัวอย่าง:

task auto_invoice: :environment do
  if Application.feature_disabled?(:auto_invoice)
    $stderr.puts 'Feature is disabled, aborting.'
  next
end
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.