গ্রোভি: "ডিফ এক্স = 0" এর "ডিএফ" এর উদ্দেশ্য কী?


180

নিম্নলিখিত কোডের টুকরোটিতে ( গ্রুভি সিমানটিকস ম্যানুয়াল পৃষ্ঠা থেকে নেওয়া ), কীওয়ার্ড সহ অ্যাসাইনমেন্টটি উপসর্গ করা উচিত def?

def x = 0
def y = 5

while ( y-- > 0 ) {
    println "" + x + " " + y
    x++
}

assert x == 5

defশব্দ মুছে ফেলা হতে পারে, এবং এই স্নিপেট একই ফল হবে। সুতরাং কীওয়ার্ডের প্রভাব কী def?

উত্তর:


278

এটি বেসিক স্ক্রিপ্টগুলির জন্য সিনট্যাকটিক চিনি। "ডিফ" কীওয়ার্ডটি ছাড়াই বর্তমান স্ক্রিপ্টটির জন্য বাইন্ডিংগুলিতে পরিবর্তনশীল রাখে এবং গ্রোভি এটি (বেশিরভাগ ক্ষেত্রে) বিশ্বব্যাপী স্কোপযুক্ত ভেরিয়েবলের মতো আচরণ করে:

x = 1
assert x == 1
assert this.binding.getVariable("x") == 1

পরিবর্তে ডিএফ কীওয়ার্ড ব্যবহার করা স্ক্রিপ্ট বাইন্ডিংগুলিতে ভেরিয়েবলটি রাখে না:

def y = 2

assert y == 2

try {
    this.binding.getVariable("y") 
} catch (groovy.lang.MissingPropertyException e) {
    println "error caught"
} 

মুদ্রণ: "ত্রুটি ধরা পড়ে"

বৃহত্তর প্রোগ্রামগুলিতে ডিএফ কীওয়ার্ড ব্যবহার করা গুরুত্বপূর্ণ কারণ এটি স্কোপটি খুঁজে পেতে পারে এবং এনক্যাপসুলেশন সংরক্ষণে সহায়তা করতে পারে এমন স্কোপটি সংজ্ঞায়িত করতে সহায়তা করে।

আপনি যদি আপনার স্ক্রিপ্টে কোনও পদ্ধতি সংজ্ঞায়িত করেন তবে মূল স্ক্রিপ্টের শরীরে "ডিফ" দিয়ে তৈরি হওয়া ভেরিয়েবলগুলিতে এর অ্যাক্সেস থাকবে না কারণ এগুলি সুযোগে নেই:

 x = 1
 def y = 2


public bar() {
    assert x == 1

    try {
        assert y == 2
    } catch (groovy.lang.MissingPropertyException e) {
        println "error caught"
    }
}

bar()

মুদ্রণ "ত্রুটি ধরা"

"Y" ভেরিয়েবলটি ফাংশনের অভ্যন্তরে নেই। "এক্স" সুযোগে রয়েছে কারণ গ্রোভি চলকের জন্য বর্তমান স্ক্রিপ্টের বাইন্ডিংগুলি পরীক্ষা করবে। যেমনটি আমি আগেই বলেছি, এটি দ্রুত এবং নোংরা স্ক্রিপ্টগুলি দ্রুত টাইপ করতে (প্রায়শই একটি লাইনার) দ্রুত তৈরি করার জন্য এটি সিনট্যাকটিক চিনি।

বৃহত্তর স্ক্রিপ্টগুলিতে ভাল অনুশীলন হ'ল "ডিএফ" কীওয়ার্ডটি সর্বদা ব্যবহার করা যাতে আপনি অদ্ভুত স্কোপিং ইস্যুগুলিতে না চলে যান বা ভেরিয়েবলগুলির সাথে হস্তক্ষেপ না করেন যা আপনি চান না।


36

টেডের উত্তর স্ক্রিপ্টগুলির জন্য দুর্দান্ত; বেনের উত্তর ক্লাসগুলির জন্য মান।

বেন যেমন বলেছেন, এটিকে "অবজেক্ট" হিসাবে ভাবেন - তবে এটি অনেক শীতল যে এটি আপনাকে অবজেক্ট পদ্ধতিতে সীমাবদ্ধ রাখে না। এর সাথে আমদানির ক্ষেত্রে ঝরঝরে প্রভাব পড়ে।

যেমন এই স্নিপেটে আমাকে ফাইলচ্যানেল আমদানি করতে হবে

// Groovy imports java.io.* and java.util.* automatically
// but not java.nio.*

import java.nio.channels.*

class Foo {
    public void bar() {
        FileChannel channel = new FileInputStream('Test.groovy').getChannel()
        println channel.toString()
    }
}

new Foo().bar()

উদাহরণস্বরূপ তবে এখানে যতক্ষণ ক্লাসপথে রয়েছে ততক্ষণ আমি কেবল 'উইং এটি' করতে পারি

// Groovy imports java.io.* and java.util.* automatically
// but not java.nio.*
class Foo {
    public void bar() {
        def channel = new FileInputStream('Test.groovy').getChannel()
        println channel.toString()
    }
}

new Foo().bar()

1
কেন আপনাকে new FileInputStream('Test.groovy').getChannel()আমদানি করার অনুমতি দেওয়া হয়েছিল ?
আলেকজান্ডার সুর্যাপেল

3
@ আলেকজান্ডারসুরফেল "যতক্ষণ ক্লাসপথে সমস্ত কিছু রয়েছে"
হ্যানো

30

এই পৃষ্ঠা অনুসারে , defকোনও প্রকার নামের জন্য প্রতিস্থাপন এবং এটির জন্য একটি উপাধি হিসাবে সহজেই ভাবা যেতে পারে Object(উদাহরণস্বরূপ যে আপনি টাইপটির বিষয়ে চিন্তা করেন না)।


12

যতদূর এই একক স্ক্রিপ্টটি সম্পর্কিত তেমন ব্যবহারিক পার্থক্য নেই।

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

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


8

"ডিএফ" এর কারণটি গ্রোভিকে বলা হয় যে আপনি এখানে একটি ভেরিয়েবল তৈরির পরিকল্পনা করছেন। এটি গুরুত্বপূর্ণ কারণ আপনি দুর্ঘটনাক্রমে কোনও পরিবর্তনশীল তৈরি করতে চান না।

এটি স্ক্রিপ্টগুলিতে কিছুটা গ্রহণযোগ্য (গ্রোভি স্ক্রিপ্টস এবং গ্রোভিশ আপনাকে এটি করার অনুমতি দেয়), তবে প্রোডাকশন কোডে এটি এমন একটি বৃহত্তম খারাপ যা আপনি আসতে পারেন যেটির জন্য আপনাকে অবশ্যই সমস্ত আসল গ্রোভি কোডে ডিফের সাথে একটি ভেরিয়েবল সংজ্ঞায়িত করতে হবে (একটি অভ্যন্তরীণ কিছু) শ্রেণী)।

এটি কেন খারাপ এটির একটি উদাহরণ এখানে। আপনি যদি নিম্নলিখিত কোডটি অনুলিপি করে এবং গ্রোভিশে পেস্ট করেন তবে এটি চালিত হবে (দৃ the় ব্যর্থতা ছাড়াই) run

bill = 7
bi1l = bill + 3
assert bill == 7

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

গুরুত্বহীন স্ক্রিপ্টগুলি / কনসোল ইনপুটগুলিতে (গ্রোভি কনসোলের মতো) এটি কিছুটা গ্রহণযোগ্য কারণ স্ক্রিপ্টের পরিধি সীমিত। আমি মনে করি গ্রোভির একমাত্র কারণ আপনাকে স্ক্রিপ্টগুলিতে এটি করার অনুমতি দেয় তা হ'ল ডিএসএলকে রুবির মতো করে সমর্থন করা (যদি আপনি আমাকে জিজ্ঞাসা করেন তবে একটি খারাপ বাণিজ্য বন্ধ রয়েছে, তবে কিছু লোক ডিএসএলকে ভালবাসে)


5

আসলে, আমি মনে করি না যে এটি একই রকম আচরণ করবে ...

গ্রোভির ভেরিয়েবলগুলি এখনও ঘোষণাপত্রের প্রয়োজন, কেবল টাইপড ঘোষণাপত্র নয়, ডান দিকের দিক থেকে সাধারণত গ্রোভির পক্ষে ভেরিয়েবলটি টাইপ করার জন্য পর্যাপ্ত তথ্য থাকে।

আমি যখন কোনও ভেরিয়েবল ব্যবহার করার চেষ্টা করি যা আমি ডিএফ বা কোনও প্রকারের সাথে ঘোষণা করি নি, তখন আমি একটি ত্রুটি পেয়েছি "এ জাতীয় কোনও সম্পত্তি নেই", কারণ এটি ধরে নেওয়া হয় যে আমি কোড সহ ক্লাসের সদস্য ব্যবহার করছি using

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