ব্রেক / প্রস্থান স্ক্রিপ্ট


87

আমার একটি প্রোগ্রাম রয়েছে যা কিছু ডেটা বিশ্লেষণ করে এবং কয়েকশ লাইনের দীর্ঘ।

প্রোগ্রামের খুব প্রথম দিকে, আমি কিছু মান নিয়ন্ত্রণ করতে চাই এবং পর্যাপ্ত ডেটা না থাকলে আমি প্রোগ্রামটি শেষ করে আর কনসোলটিতে ফিরে আসতে চাই। অন্যথায়, আমি বাকী কোডটি কার্যকর করতে চাই।

আমি চেষ্টা করেছি break, browserএবং quitতাদের কেউ প্রোগ্রাম বাকি সঞ্চালনের থামাতে (এবং quitপাশাপাশি সম্পূর্ণরূপে প্রস্থান আর, যা কিছু আমি ঘটতে করতে চান না যেমন ফাঁসি স্টপ)। আমার শেষ অবলম্বন if-elseনীচে হিসাবে একটি বিবৃতি তৈরি করছে:

 if(n < 500){}
 else{*insert rest of program here*}

তবে এটি খারাপ কোডিং অনুশীলনের মতো বলে মনে হচ্ছে। আমি কিছু অনুপস্থিত করছি?


4
quitঅবশ্যই অবশ্যই প্রোগ্রামটির বাকী কাজ সম্পাদন বন্ধ করে দেয়। দয়া করে একটি পুনরুত্পাদনযোগ্য উদাহরণ সরবরাহ করুন
জোশুয়া উলরিচ

@ জ্যাকবার্কহেড - আমার কোডটি কি উপরের (খালি যদি বিবৃতি দিয়ে থাকে) যাওয়ার সর্বোত্তম উপায়, তবে? @ জোশুয়া উলরিচ, quitসমস্ত আর থেকে প্রস্থান করেছেন, তবে আমি আর কনসোলে ফিরে যেতে চাই কারণ আমার উদ্দেশ্যগুলির জন্য প্রোগ্রামটি উন্মুক্ত থাকা দরকার।
ব্যবহারকারী 2588829

কোন প্রোগ্রাম বলতে কী বোঝ? আপনি কি বোঝাতে চেয়েছেন যে আপনি লিখেছেন এমন কোনও ফাংশন আপনি চালাচ্ছেন বা আপনি কোনও স্ক্রিপ্টে উত্সাহ দিচ্ছেন?
গ্যাভিন সিম্পসন

যদি অন্যথায় সম্ভবত এটি হ্যান্ডেল করার সঠিক উপায়। ব্যতিক্রমগুলি এমন পরিস্থিতিতে রয়েছে যা যদি সবকিছু সঠিকভাবে ব্যবহার হয় তবে ঘটবে না। যদি এটি এমন কিছু ঘটতে পারে এবং আপনি কীভাবে এটি পরিচালনা করতে জানেন তবে সাধারণ নিয়ন্ত্রণ প্রবাহ ব্যবহার করুন।
ম্যাথু

উত্তর:


62

আপনি stopifnot()যদি প্রোগ্রামটি কোনও ত্রুটি তৈরি করতে চান তবে আপনি ফাংশনটি ব্যবহার করতে পারেন :

foo <- function(x) {
    stopifnot(x > 500)
    # rest of program
}

+1! আমি অনুমান করি যে ফাংশনটি fooস্ক্রিপ্টের শুরু বলা উচিত এবং এতে অন্যান্য বৈধতা নিয়ন্ত্রণ থাকা উচিত ...
আগস্ট

22
stopifnotসুবিধাজনক তবে ব্যবহার করে একটি কারুকাজ করা প্রতিক্রিয়া if(x < 500) { stop("Not enough observations in 'x': n < 500")}পছন্দ হতে পারে। এছাড়াও, এটি যদি ব্যাচের কাজের জন্য কিছু হয় তবে কোনও ত্রুটি না ছুঁড়েই সমস্যাটি পরিচালনা করা কার্যকর।
গ্যাভিন সিম্পসন

4
ওপিকে বিভ্রান্ত করার চেষ্টা বন্ধ করুন। তিনি যা চান তা হ'ল প্রস্থান () বা স্টপ (), স্টিপফনোট () নয়।
stackoverflowuser2010

10
@ stackoverflowuser2010 তিনি চান না quit(প্রশ্ন দেখতে পাবেন!) আমি এমনকি মনে করি না stopএর stopifnotসবচেয়ে ভালো উপায় এই হ্যান্ডেল করতে হয়; stopএকটি ত্রুটি নিক্ষেপ করে, পুরো স্ক্রিপ্টটি কেবল বাতিল করতে হবে। যদিও stopifnot(বা stop) উত্তর ওপিকে সবচেয়ে ভাল লেগেছে, ত্রুটি ছাড়াই পরিষ্কারভাবে বেরিয়ে আসার জন্য একটি ফাংশন লিখলে পরিস্থিতি বিস্তৃত ক্ষেত্রে আরও বেশি উপকারী। বড় ডেটা বিশ্লেষণ কাজের জন্য প্রচুর দীর্ঘমেয়াদী স্ক্রিপ্ট লিখিত থাকা, সমস্যাগুলি হ'ল সমস্যাটি পরিচালনা করা এবং পরিষ্কারভাবে ফিরে আসার পরিবর্তে ত্রুটি ছুঁড়ে ফেলার চেয়ে আর বিরক্তিকর কিছুই নয়। তবে স্পষ্টত আমি জানি না আমি কী সম্পর্কে কথা বলছি ...
গ্যাভিন সিম্পসন

আপনি কি দয়া করে @ গ্যাভিনসিম্পসনকে ত্রুটি ছুঁড়ে দেওয়ার বিষয়ে আপনার মন্তব্যটি পরিষ্কার করতে পারেন? আমি যখন চেষ্টা stop("my message")করি তখন আমি টার্মিনালে মুদ্রিত হই Error: "my message" Execution halted। সুতরাং এটি একটি ত্রুটি বার্তা আউটপুট দেখায়, তবে আপনি কি বলছেন যে এটি একটি ত্রুটি "নিক্ষেপ" করে না? (অর্থাত্ এটি কোনও ব্যাচের কাজ বন্ধ করবে না যা এটি বাতিল করার জন্য নির্ধারিত হয়েছে এমন কোনও স্ক্রিপ্ট যদি এটির ত্রুটি বলে) ধন্যবাদ! (এই মুহূর্তে আমি Rscript সহ স্ক্রিপ্টের আহ্বান করছি)
rrr

14

সুন্দর নয়, তবে এখানে একটি exit()কমান্ড বাস্তবায়নের একটি উপায় যা আমার পক্ষে কাজ করে।

exit <- function() {
  .Internal(.invokeRestart(list(NULL, NULL), NULL))
}

print("this is the last message")
exit()
print("you should not see this")

কেবলমাত্র হালকাভাবে পরীক্ষা করা হয় তবে আমি এটি চালানোর সময় দেখি this is the last messageএবং তারপরে কোনও ত্রুটি বার্তা ছাড়াই স্ক্রিপ্টটি বাতিল হয়ে যায়।


ডাউনসাইড হ'ল এটি কোনও CRAN প্যাকেজে কোডের জন্য অনুমোদিত নয়। সুতরাং আপনি যদি সিআরএএন-তে আপলোড করতে চান এমন কোনও প্যাকেজটিতে আপনি যদি ব্যবহার করার ইচ্ছা করেন তবে এটিতে একটি সতর্কতা আসবে R CMD CHECK
এমএস বেরেন্ডস

4
হ্যাঁ, এটি দেখতে সিস্টেম ফাংশনটির মতো বেশি। যদি দোভাষীর অভ্যন্তরীণ বিবরণ পরিবর্তন করা হয়, তবে এটি পৃথক প্যাকেটের পরিবর্তে আর কোরের একটি অংশের চেয়ে ভাল হতে পারে? আর সোর্স কোডের মাধ্যমে আমি বিভিন্ন পথ অনুসরণ করে এটি খুঁজে পেয়েছি কীভাবে কোনও ত্রুটি বার্তা নির্গত না হয়ে আমি দোভাষী থেকে বেরিয়ে আসার জন্য সঠিক জায়গায় পৌঁছাতে পারি see আমি সেখানে পৌঁছানোর মতো অনেকগুলি উপায় পাই নি; এই কারণেই আমি ব্যবহার করি .invokeRestartযা ঘুরে ফিরে মনে হয় .Internal
জোচেন

ওহ হ্যাঁ, সিআরএএন নীতিগুলি বাদে, আমি মনে করি এটি একটি দুর্দান্ত সমাধান! আমাকে আপনার একটি +10 প্রতিনিধি সরবরাহ করতে দিন;)
এমএস বেরেন্ডস

অদ্ভুত আমি কেবল এটি চেষ্টা করেছি এবং সর্বশেষ আউটপুট লাইনটি ছিল [1] "আপনি এই" আর ভার্সনটি দেখবেন না "3.4.3 (2017-11-30) প্ল্যাটফর্ম: x86_64-pc-linux-gnu (-৪-বিট) এর অধীনে চলছে: রেড হ্যাট এন্টারপ্রাইজ লিনাক্স সার্ভার 6.10 (সান্টিয়াগো)
কোডিংম্যাটার্স

4
আমি এটি নিয়ে কাজ করতে পেরেছিexit <- function() { invokeRestart("abort") }
ড্রপলেট

12

আপনার যদি-অন্য নির্মাণ বিপরীত:

if(n >= 500) {
  # do stuff
}
# no need for else

4
যথেষ্ট সহজ এবং আমি অনুমান করি যে এটি আমি করতে পারি সেরা, ধন্যবাদ
ব্যবহারকারী 2588829

9

সম্পাদনা: মনে হচ্ছে ওপি একটি দীর্ঘ স্ক্রিপ্ট চালাচ্ছে, সেক্ষেত্রে মান নিয়ন্ত্রণের পরে স্ক্রিপ্টের অংশটি কেবল একটির জন্য আবশ্যক needs

if (n >= 500) {

.... long running code here

}

যদি কোনও ফাংশন ভেঙে যায় , আপনি সম্ভবত return()পরিষ্কার বা স্পষ্টতই চাইবেন ।

উদাহরণস্বরূপ, একটি সুস্পষ্ট ডাবল রিটার্ন

foo <- function(x) {
  if(x < 10) {
    return(NA)
  } else {
    xx <- seq_len(x)
    xx <- cumsum(xx)
  }
  xx ## return(xx) is implied here
}

> foo(5)
[1] 0
> foo(10)
 [1]  1  3  6 10 15 21 28 36 45 55

দ্বারা return()উহ্য হচ্ছে, আমি বলতে চাচ্ছি যেন আপনি কাজ শেষ করলেন শেষ লাইনটি যে return(xx), কিন্তু এটা সামান্য বেশি কল বন্ধ ত্যাগ করার কার্যকরী return()

কিছু একাধিক রিটার্ন খারাপ শৈলী ব্যবহার বিবেচনা; দীর্ঘ ফাংশনে, কোথায় ফাংশনটি প্রস্থান করে তা ট্র্যাক করে রাখা কঠিন বা ত্রুটির প্রবণ হয়ে উঠতে পারে। অতএব বিকল্পটি হ'ল একক রিটার্ন পয়েন্ট থাকা, তবে ক্লজটি ব্যবহার করে রিটার্ন অবজেক্ট পরিবর্তন করুন if () else ()। যেমন একটি পরিবর্তন foo()হতে হবে

foo <- function(x) {
  ## out is NA or cumsum(xx) depending on x
  out <- if(x < 10) {
    NA
  } else {
    xx <- seq_len(x)
    cumsum(xx)
  }
  out ## return(out) is implied here
}

> foo(5)
[1] NA
> foo(10)
 [1]  1  3  6 10 15 21 28 36 45 55

আমি এটি সম্পর্কেও ভেবেছিলাম, তবে এটি পরিষ্কার নয় যে ওপি কোনও ফাংশন ভেঙে ফেলার বিষয়ে কথা বলছে।
থমাস

হ্যাঁ, টমাস ঠিক বলেছেন - আমি কোনও ফাংশন ভেঙে ফেলার কথা বলছি না।
ব্যবহারকারী 2588829

4
@ ব্যবহারকারী 2588829 আপনি এটি একটি 100+ লাইন স্ক্রিপ্টের চেয়ে আর হিসাবে একটি ফাংশন হিসাবে রাখলে অনেক বেশি ভাল হতে চাই।
গ্যাভিন সিম্পসন

@ গ্যাভিনসিম্পসন ওহ, আমি এখনও আর-তে নতুন তাই আমি এটি জানতাম না। যদি আমি এটি একটি 100+ লাইন ফাংশন হিসাবে সংজ্ঞায়িত করি তবে এটি কি আরও ভাল অনুশীলন?
ব্যবহারকারী 2588829

4
@ ব্যবহারকারী 2588829 হ্যাঁ, আরও ভাল। আপনি ফাংশনের আর্গুমেন্টগুলি নিয়ন্ত্রণ করেন যাতে প্রয়োজনীয় কি তা পাস করতে পারে। এছাড়াও, বিশ্লেষণগুলি চালানোর জন্য 100+ লাইন কোডের স্রোসিংয়ের পরিবর্তে আপনি যা করেন myFun(arg1, arg2, arg3)ইত্যাদি It এটি জিনিসগুলি সংগঠিত করার পক্ষে আরও অনেক ভাল উপায়।
গ্যাভিন সিম্পসন

9

সম্ভবত আপনি কিছু সময় একটি দীর্ঘ স্ক্রিপ্ট চালানো বন্ধ করতে চান। অর্থাত্ যেমন আপনি সি বা পাইথনে হার্ড কোডটি একটি প্রস্থান () করতে চান।

print("this is the last message")
stop()
print("you should not see this")

4
এই কোডের জন্য আমি ত্রুটি বার্তা পাই Error in eval(expr, envir, enclos) :
জোচেন

4
হ্যাঁ, মৃত্যুদন্ড কার্যকর করা বন্ধ হয়ে যায়। কাকতালীয়ভাবে, আপনি যদি প্রতিস্থাপন stop()করেন exit()বা এর সাথে please.stop.now(), স্ক্রিপ্টটিও বন্ধ হয়ে যায় (কেবল ত্রুটির বার্তা অবশ্যই আলাদা)।
জোচেন

4
@ জোচেন stop()কমান্ডের ভিতরে একটি উদ্ধৃত বাক্যাংশ যুক্ত করা অন্যান্য বার্তাগুলির থেকে এই "ত্রুটি" পার্থক্য করতে সহায়তা করতে পারে। উদাহরণস্বরূপ: একা থেকে stop("Manual break inserted here")আরও তথ্যপূর্ণ হতে পারে stop()
ওমর ওয়েভ

3

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

continue <- TRUE

tryCatch({
     # You do something here that needs to exit gracefully without error.
     ...

     # We now say bye-bye         
     stop("exit")

}, error = function(e) {
    if (e$message != "exit") {
        # Your error message goes here. E.g.
        stop(e)
    }

    continue <<-FALSE
})

if (continue) {
     # Your code continues here
     ...
}

cat("done.\n")

মূলত, আপনি একটি নির্দিষ্ট কোডের ব্লকের ধারাবাহিকতা বা না তা নির্দেশ করতে একটি পতাকা ব্যবহার করেন। তারপরে আপনি কোনও stop()ক্রিয়াকলাপের ত্রুটি হ্যান্ডলারে একটি স্বনির্ধারিত বার্তা প্রেরণ করতে ফাংশনটি ব্যবহার করেন tryCatch()। যদি ত্রুটি হ্যান্ডলার আপনার বার্তাটি কৌতূহলীভাবে প্রস্থান করার জন্য গ্রহণ করে, তবে এটি কেবল ত্রুটিটিকে উপেক্ষা করে এবং ধারাবাহিকতা পতাকাটি সেট করে FALSE


0

আপনি pskillফাংশনটি ব্যবহার করতে পারেনR বর্তমান সরঞ্জামটি বাধাগ্রস্থ করতে এবং কনসোলে ফিরে আসতে "সরঞ্জামগুলি" প্যাকেজে । কংক্রিটলিপি, আমি প্রতিটি স্ক্রিপ্টের শুরুতে উত্স সূচনা ফাইলটিতে নিম্নলিখিত ফাংশনটি সংজ্ঞায়িত করেছি। তবে আপনার কোডের শুরুতে এটি সরাসরি অনুলিপি করতে পারেন। তারপরে ফ্লাইতে halt()স্ক্রিপ্ট সম্পাদন বন্ধ করতে আপনার কোডের যে কোনও পয়েন্টে .োকান। এই ফাংশনটি জিএনইউ / লিনাক্সে ভালভাবে কাজ করে এবং Rডকুমেন্টেশন থেকে বিচার করে এটি উইন্ডোতেও কাজ করা উচিত (তবে আমি পরীক্ষা করে দেখিনি)।

# halt: interrupts the current R process; a short iddle time prevents R from
# outputting further results before the SIGINT (= Ctrl-C) signal is received 
halt <- function(hint = "Process stopped.\n") {
    writeLines(hint)
    require(tools, quietly = TRUE)
    processId <- Sys.getpid() 
    pskill(processId, SIGINT)
    iddleTime <- 1.00
    Sys.sleep(iddleTime)
}

> পিস্কিল (প্রসেসআইডি, সিগিন্ট) সেশনটি বন্ধ করে এবং আর স্টুডিও থেকেও ব্যবহারকারীকে কিক্স করে। এটি বেশ বিপজ্জনক তবে কার্যকরী ....
এস্পান্ত

এটি আরস্টুডিও ক্র্যাশ করবে তা জানতেন না, তবে একই বিষয়টিতে আলোচনা করা হয়েছে: stackoverflow.com/questions/32820534/… যদিও লিনাক্সে, আমার সমাধানটি ঠিক কাজ করে। স্টিফনোটের উপর এর সুবিধা হ'ল স্টিপফনট () ত্রুটি বার্তাটি প্রদর্শিত হয় না।
ফ্রান্সোইস টোন্নো

আমি উইন্ডোজ পরীক্ষা করে দেখেছি এবং এটি উন্মাদ আচরণ করে। যাই হোক ধন্যবাদ. আমি পিস্কিল পছন্দ করি
এস্পান্ত

0

এখানে:

if(n < 500)
{
    # quit()
    # or 
    # stop("this is some message")
}
else
{
    *insert rest of program here*
}

উভয়ই quit()এবং stop(message)আপনার স্ক্রিপ্টটি প্রস্থান করবে। আপনি যদি আর-কমান্ড প্রম্পট থেকে আপনার স্ক্রিপ্টটি উত্সাহ দিচ্ছেন, তবে quit()আর থেকেও প্রস্থান করবেন।


7
ইতিমধ্যে পোস্ট করা সদৃশদের উত্তরগুলি পোস্ট করা খারাপ অনুশীলন।
থমাস

@ থমাস কোন উত্তরটি এই সদৃশ করে? আমি কেবল থামাতে এবং ছেড়ে দেওয়া উভয় ব্যবহার করে এই উত্তরটি দেখতে পাচ্ছি এবং আসলে তাদের মধ্যে পার্থক্যটি ব্যাখ্যা করছি।

@ থমাস: আমার উত্তরটি সদৃশ করে ঠিক কী উত্তর দেয় তা ব্যাখ্যা কর।
stackoverflowuser2010

@ থমাস: আপনার সমালোচনা সম্পর্কে আমি একটি প্রশ্ন তুলেছি। আমি আপনার উত্তর দেওয়ার জন্য অপেক্ষা করছি।
stackoverflowuser2010

4
@ নেটস্কিংকের উত্তর ব্যবহার করেছে stop()এবং ওপি ইতিমধ্যে মন্তব্যগুলিতে ইঙ্গিত দিয়েছে যে তারা চায় না quit()...
বেন বলকার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.