एक नौसिखिया के बारे में रूबी गोचकों को क्या चेतावनी दी जानी चाहिए? [बन्द है]


108

मैंने हाल ही में रूबी प्रोग्रामिंग भाषा सीखी है, और सभी में यह एक अच्छी भाषा है। लेकिन मैं यह देखकर काफी हैरान था कि यह उतना सरल नहीं था जितना मैंने उम्मीद की थी। अधिक सटीक रूप से, "कम से कम-आश्चर्य का शासन" मुझे बहुत सम्मानित नहीं लगा (बेशक यह काफी व्यक्तिपरक है)। उदाहरण के लिए:

x = true and false
puts x  # displays true!

और प्रसिद्ध:

puts "zero is true!" if 0  # zero is true!

अन्य "गोत्च्स" आप रूबी नौसिखिया के बारे में क्या चेतावनी देंगे?


@ phrase.insert (0, p) ठीक है @ phrase.insert (p) NOTHING होता है @phrases << p # OK
Anno2001

क्यों true and falseसच है?
जर्गेन पॉल

3
क्योंकि "x = सत्य और असत्य" को वास्तव में "(x = true) और असत्य" कहा जाता है। यह ऑपरेटर पूर्वता की बात है: "और" की तुलना में "=" की प्राथमिकता कम है। अधिकांश अन्य भाषाओं में रिवर्स प्राथमिकता है, मुझे नहीं पता कि उन्होंने रेल में इस आदेश को क्यों चुना, मुझे यह बहुत भ्रमित लगता है। यदि आप "सामान्य" व्यवहार चाहते हैं, तो बस "x = (सही और गलत)" टाइप करें, तो x गलत होगा।
मिनीक्वायार्क

4
एक और उपाय है "&&" और "||" "और" और "या" के बजाय: वे अपेक्षा के अनुरूप व्यवहार करते हैं। उदाहरण के लिए: "x = true && false" का परिणाम x गलत है।
मिनीक्वायार्क

"कम से कम आश्चर्य के सिद्धांत का मतलब है कम से कम मेरे आश्चर्य का सिद्धांत ।" से en.wikipedia.org/wiki/Ruby_(programming_language)#Philosophy ही अजगर के लिए चला जाता है। मैंने पायथन के निर्माता के बारे में इसी तरह का उद्धरण दिया था, लेकिन मैं भूल गया कि यह कहाँ था।
डेरेक नादज़ा

जवाबों:


59

विकिपीडिया रूबी गोत्र

लेख से:

  • नाम जो एक बड़े अक्षर से शुरू होते हैं उन्हें स्थिरांक के रूप में माना जाता है, इसलिए स्थानीय चर को लोअरकेस अक्षर से शुरू करना चाहिए।
  • वर्ण $और @पर्ल डेटा प्रकार को पर्ल के रूप में इंगित नहीं करते हैं, बल्कि गुंजाइश रिज़ॉल्यूशन ऑपरेटरों के रूप में कार्य करते हैं।
  • फ्लोटिंग पॉइंट नंबरों को निरूपित करने के लिए, एक शून्य अंक ( 99.0) या एक स्पष्ट रूपांतरण ( 99.to_f) के साथ पालन करना चाहिए । यह एक बिंदु ( 99.) को जोड़ने के लिए अपर्याप्त है , क्योंकि संख्याओं को विधि सिंटैक्स के लिए अतिसंवेदनशील है।
  • गैर बूलियन डेटा की बूलियन मूल्यांकन सख्त है: 0, ""और []सभी के लिए मूल्यांकन किया जाता है true। C में, अभिव्यक्ति का 0 ? 1 : 0मूल्यांकन 0(यानी असत्य) है। रूबी में, हालांकि, इसकी पैदावार होती है 1, क्योंकि सभी संख्याओं का मूल्यांकन होता है true; केवल nilऔर falseमूल्यांकन करने के लिए false। इस नियम के लिए एक नियम यह है कि रूबी कन्वेंशन के तरीके - उदाहरण के लिए, नियमित-अभिव्यक्ति खोज - रिटर्न नंबर, स्ट्रिंग्स, सूचियां, या सफलता पर अन्य गैर-झूठे मूल्य, लेकिन nilविफलता पर (उदाहरण के लिए, बेमेल)। इस कन्वेंशन का उपयोग स्मालटाक में भी किया जाता है, जहां केवल विशेष वस्तुओं trueऔर falseबूलियन अभिव्यक्ति में उपयोग किया जा सकता है।
  • 1.9 से पहले के संस्करणों में एक चरित्र डेटा प्रकार (सी की तुलना में, जो charवर्णों के लिए प्रकार प्रदान करता है ) का अभाव है । स्लाइसिंग स्ट्रिंग्स के कारण यह आश्चर्यचकित कर सकता है: "abc"[0]पैदावार 97(एक पूर्णांक, स्ट्रिंग में पहले वर्ण के ASCII कोड का प्रतिनिधित्व करता है); (लंबाई 1 का एक विकल्प) का "a"उपयोग करने के लिए "abc"[0,1]या "abc"[0].chr
  • statement until expressionअन्य भाषाओं के समकक्ष कथनों (जैसे do { statement } while (not(expression));C / C ++ / ...) के विपरीत, संकेतन वास्तव में कभी भी कथन नहीं चलाता है यदि अभिव्यक्ति पहले से है true। ऐसा इसलिए है क्योंकि statement until expressionवास्तव में सिंटैक्टिक शुगर ओवर है

    until expression
      statement
    end
    

    के बराबर है, जिसमें C / C ++ की while (not(expression)) statement;तरह statement if expressionही इसके बराबर है

    if expression
      statement
    end
    

    हालाँकि, संकेतन

    begin
      statement
    end until expression
    

    रूबी वास्तव में एक बार बयान चलाएगी भले ही अभिव्यक्ति पहले से ही सच हो।

  • क्योंकि स्थिरांक वस्तुओं के संदर्भ होते हैं, एक स्थिरांक को बदलने से एक चेतावनी उत्पन्न होती है, लेकिन वस्तु को संशोधित करना स्वयं नहीं होता है। उदाहरण के लिए, Greeting << " world!" if Greeting == "Hello"कोई त्रुटि या चेतावनी उत्पन्न नहीं करता है। यह finalजावा में चर के समान है , लेकिन रूबी में जावा के विपरीत एक वस्तु को "फ्रीज" करने की कार्यक्षमता भी है।

कुछ विशेषताएं जो अन्य भाषाओं से अलग हैं:

  • सशर्त अभिव्यक्तियों के लिए सामान्य ऑपरेटर, andऔर or, पूर्वता के सामान्य नियमों का पालन नहीं करते हैं: की andतुलना में तंग नहीं बांधता है or। रूबी के पास अभिव्यक्ति ऑपरेटर भी हैं ||और &&जो उम्मीद के मुताबिक काम करते हैं।

  • defअंदर defक्या एक अजगर प्रोग्रामर उम्मीद कर सकते हैं ऐसा नहीं करता है:

    def a_method
        x = 7
        def print_x; puts x end
        print_x
    end
    

    यह xपरिभाषित नहीं होने के बारे में एक त्रुटि देता है। आपको एक का उपयोग करने की आवश्यकता है Proc

भाषा सुविधाएं

  • यदि विधि कई पैरामीटर लेती हैं, तो विधि तर्कों के आसपास कोष्ठकों के प्रवेश से अप्रत्याशित परिणाम हो सकते हैं। रूबी डेवलपर्स ने कहा है कि भविष्य के रूबी संस्करणों में बहु-पैरामीटर तरीकों पर कोष्ठकों की चूक को रोका जा सकता है; वर्तमान (नवंबर 2007) रूबी दुभाषिया एक चेतावनी देता है, जो लेखक ()को कोड के अस्पष्ट अर्थ से बचने के लिए नहीं छोड़ने के लिए प्रोत्साहित करता है । उपयोग नहीं करना ()अभी भी सामान्य अभ्यास है, और रूबी को मानव पठनीय डोमेन-विशिष्ट प्रोग्रामिंग भाषा के रूप में उपयोग करने के लिए विशेष रूप से अच्छा हो सकता है, जिसे विधि कहा जाता है method_missing()

1
रूबी 1.9 में चरित्र डेटा प्रकार का भी अभाव है। 1.8 में, इंडेक्स ऑपरेटर ने एक फ़िक्नम लौटाया; 1.9 में, यह एक-वर्ण स्ट्रिंग को स्लाइस करने के बराबर है।
व्हाइटक्वार्क

38

Newbies को समानता के तरीकों से परेशानी होगी :

  • a == b : जाँच करता है कि क्या a और b बराबर हैं। यह सबसे उपयोगी है।
  • a.eql? b : यह भी जाँचता है कि क्या a और b बराबर हैं, लेकिन यह कभी-कभी अधिक सख्त होता है (यह जाँच सकता है कि a और b का एक ही प्रकार है, उदाहरण के लिए)। यह मुख्य रूप से हैश में उपयोग किया जाता है।
  • a.equal? b : चेक करता है कि क्या a और b एक ही ऑब्जेक्ट (आइडेंटिटी चेक) हैं।
  • a === b : केस स्टेटमेंट्स में उपयोग किया जाता है (मैंने इसे " माचिस बी " के रूप में पढ़ा )।

इन उदाहरणों को पहले 3 तरीकों को स्पष्ट करना चाहिए:

a = b = "joe"

a==b       # true
a.eql? b   # true
a.equal? b # true (a.object_id == b.object_id)

a = "joe"
b = "joe"

a==b       # true
a.eql? b   # true
a.equal? b # false (a.object_id != b.object_id)

a = 1
b = 1.0

a==b       # true
a.eql? b   # false (a.class != b.class)
a.equal? b # false

ध्यान दें कि == , eql? और बराबर? हमेशा सममित होना चाहिए: यदि ए = बी तो बी == ए।

यह भी ध्यान दें कि == और eql? क्या दोनों को क्लास ऑब्जेक्ट के रूप में लागू किया जाता है? , तो यदि आप एक नया वर्ग बनाते हैं और चाहते हैं == और eql? सादे पहचान के अलावा कुछ और मतलब है, तो आपको उन दोनों को ओवरराइड करने की आवश्यकता है। उदाहरण के लिए:

class Person
    attr_reader name
    def == (rhs)
      rhs.name == self.name  # compare person by their name
    end
    def eql? (rhs)
      self == rhs
    end
    # never override the equal? method!
end

=== विधि अलग ढंग से व्यवहार करता है। सबसे पहले यह सममित नहीं है (ए = बी का मतलब यह नहीं है कि बी === ए)। जैसा कि मैंने कहा, आप एक === b को "एक माचिस b" के रूप में पढ़ सकते हैं। कुछ उदाहरण निम्नलिखित हैं:

# === is usually simply an alias for ==
"joe" === "joe"  # true
"joe" === "bob"  # false

# but ranges match any value they include
(1..10) === 5        # true
(1..10) === 19       # false
(1..10) === (1..10)  # false (the range does not include itself)

# arrays just match equal arrays, but they do not match included values!
[1,2,3] === [1,2,3] # true
[1,2,3] === 2       # false

# classes match their instances and instances of derived classes
String === "joe"   # true
String === 1.5     # false (1.5 is not a String)
String === String  # false (the String class is not itself a String)

मामले कथन पर आधारित है === विधि:

case a
  when "joe": puts "1"
  when 1.0  : puts "2"
  when (1..10), (15..20): puts "3"
  else puts "4"
end

इसके बराबर है:

if "joe" === a
  puts "1"
elsif 1.0 === a
  puts "2"
elsif (1..10) === a || (15..20) === a
  puts "3"
else
  puts "4"
end

यदि आप एक नए वर्ग को परिभाषित करते हैं, जिसके उदाहरण किसी प्रकार के कंटेनर या रेंज का प्रतिनिधित्व करते हैं (यदि इसमें कुछ शामिल है? या एक मैच? विधि), तो आपको इस तरह से === विधि को ओवरराइड करना उपयोगी हो सकता है :

class Subnet
  [...]
  def include? (ip_address_or_subnet)
    [...]
  end
  def === (rhs)
    self.include? rhs
  end
end

case destination_ip
  when white_listed_subnet: puts "the ip belongs to the white-listed subnet"
  when black_listed_subnet: puts "the ip belongs to the black-listed subnet"
  [...]
end

1
भी: a = 'строка'; b = 'строка'; पा == बी; a = a.force_encoding 'ASCII-8BIT'; b = b.force_encoding 'UTF-8'; पा == बी; पा === b; p.eql? ख; p. असमान? b
नकीलोन

20
  • बंदर पटकना । रूबी के पास खुली कक्षाएं हैं, इसलिए उनके व्यवहार को गतिशील रूप से रनटाइम में बदला जा सकता है ...

  • ऑब्जेक्ट अपरिभाषित तरीकों से प्रतिक्रिया दे सकते हैं यदि उन्हें ओवरराइड किया गया है method_missingया नहीं send। यह रूबी के संदेश-आधारित पद्धति आह्वान का शोषण करता है। रेल्स ' ActiveRecord प्रणाली इसका बहुत प्रभाव डालती है।


18

निम्नलिखित कोड ने मुझे चौंका दिया। मुझे लगता है कि यह एक खतरनाक गोटा है: दोनों को चलाना आसान है, और डीबग करना मुश्किल है।

(1..5).each do |number|
  comment = " is even" if number%2==0
  puts number.to_s + comment.to_s
end

यह प्रिंट:

1
2 is even
3
4 is even
5

लेकिन अगर मैं ब्लॉक से पहले comment =कुछ भी जोड़ता हूं ...

comment = nil
(1..5).each do |number|
  comment = " is even" if number%2==0
  puts number.to_s + comment.to_s
end

फिर मुझे मिलता है:

1
2 is even
3 is even
4 is even
5 is even

असल में, जब एक वैरिएबल को केवल एक ब्लॉक के अंदर परिभाषित किया जाता है, तो यह ब्लॉक के अंत में नष्ट हो जाता है, और फिर इसे nilप्रत्येक पुनरावृत्ति पर रीसेट हो जाता है । आमतौर पर आप यही उम्मीद करते हैं। लेकिन अगर वैरिएबल को ब्लॉक से पहले परिभाषित किया जाता है, तो बाहरी वेरिएबल का उपयोग ब्लॉक के अंदर किया जाता है, और इसका मान इसलिए पुनरावृत्तियों के बीच बना रहता है।

एक समाधान इसके बजाय यह लिखना होगा:

comment = number%2==0 ? " is even" : nil

मुझे लगता है कि बहुत सारे लोग (मेरे सहित) " a = b if c" के बजाय " " लिखना पसंद करते हैं a = (c ? b : nil), क्योंकि यह अधिक पठनीय है, लेकिन जाहिर है कि इसके दुष्प्रभाव हैं।


4
आप बस (1..5) कर संख्या के साथ outher गुंजाइश चर छाया कर सकते हैं | संख्या; टिप्पणी | ..... यहाँ पढ़ें stackoverflow.com/questions/1654637/…
Julzgür

6
यह मुझे तर्कसंगत लगता है। यह स्कोपिंग अन्य भाषाओं की विशिष्ट है, यह सिर्फ वाक्यविन्यास है जो अलग है।
जी।

हालांकि, आप a = (b if c)टर्नरी के बिना, वांछित प्रभाव प्राप्त करने के लिए लिख सकते हैं । ऐसा इसलिए है क्योंकि b if cअगर cगलत है तो शून्य का मूल्यांकन करता है।
कैमरन मार्टिन

16

जब superकोई तर्कों के साथ कॉल नहीं किया जाता है, तो ओवरराइड विधि को वास्तव में ओवरराइडिंग विधि के समान तर्कों के साथ कहा जाता है।

class A
  def hello(name="Dan")
    puts "hello #{name}"
  end
end

class B < A
  def hello(name)
    super
  end
end

B.new.hello("Bob") #=> "hello Bob"

वास्तव superमें बिना किसी तर्क के कॉल करने के लिए , आपको कहने की आवश्यकता है super()


3
अगर B#helloहै name = 42पहले super, तो यह "हैलो 42" कहते हैं।
एंड्रयू ग्रिम

14

ब्लॉक और विधियां डिफ़ॉल्ट रूप से अंतिम पंक्ति का मान लौटाती हैं। putsडिबगिंग उद्देश्यों के लिए अंत में बयान जोड़ना अप्रिय दुष्प्रभाव पैदा कर सकता है


13

वाह, यह एक गोत्चा है जिसके बारे में मुझे नहीं पता था। धन्यवाद!
मिनीक्वार

यह संरक्षित तरीकों के मामले में करता है, बल्कि जटिल तरीके से।
ताव

11

मुझे कक्षा चर, वर्ग विशेषताओं और वर्ग विधियों को समझने में बहुत परेशानी हुई। यह कोड एक नौसिखिया की मदद कर सकता है:

class A
  @@classvar = "A1"
  @classattr = "A2"
  def self.showvars
    puts "@@classvar => "+@@classvar
    puts "@classattr => "+@classattr
  end
end

A.showvars
  # displays:
  # @@classvar => A1
  # @classattr => A2

class B < A
  @@classvar = "B1"
  @classattr = "B2"
end

B.showvars
  # displays:
  # @@classvar => B1
  # @classattr => B2

A.showvars
  # displays:
  # @@classvar => B1   #Class variables are shared in a class hierarchy!
  # @classattr => A2   #Class attributes are not

1
हाँ, वर्ग चर मुश्किल हो सकते हैं। मुझे लगता है कि सबसे अनुभवी रूबिस्ट कहेंगे कि यह उनसे बचने के लिए बुद्धिमान है, क्योंकि आमतौर पर उनके बिना किसी समस्या को हल करने के अन्य तरीके हैं। कुछ भाषा प्रेमी यह भी कहेंगे कि रूबी के वर्ग चर खराब तरीके से भाषा के स्तर पर तैयार किए गए हैं।
डेविड जे।

8

एक बात जो मैंने सीखी थी, वह था ऑपरेटर का उपयोग करना = = सावधानी से। और विशेष ध्यान रखें यदि आप बूलियंस के साथ काम कर रहे हैं। मैं आमतौर पर एक '=' b 'को सभी को पकड़ने के लिए' a 'को एक डिफ़ॉल्ट मान देता था यदि सब कुछ विफल रहा और' a 'शून्य बना रहा। लेकिन अगर कोई गलत है और ख सच्चा है, तो उसे सही ठहराया जाएगा।


आप उपयोग कर सकते हैं a = b if a.nil?या @a = b unless defined?(@a)
एंड्रयू ग्रिम

8
  • ब्लॉक वास्तव में समझने के लिए महत्वपूर्ण हैं, वे हर जगह उपयोग किए जाते हैं।

  • आपको विधि पैरामीटर के आसपास कोष्ठक की आवश्यकता नहीं है। आप उनका उपयोग करते हैं या नहीं, आप पर निर्भर है। कुछ लोग कहते हैं कि आपको हमेशा उनका उपयोग करना चाहिए

  • अपवाद से निपटने के लिए उठाएं और बचाव का उपयोग करें, फेंक और पकड़ नहीं।

  • आप उपयोग कर सकते हैं ;लेकिन आपको तब तक नहीं करना है जब तक आप एक पंक्ति में कई चीजें नहीं डालना चाहते हैं।


यदि आप रूबी 1.8.6 से आगे जाने की योजना नहीं बनाते हैं, तो आप जितना चाहें उतना मुर्गियों की उपेक्षा करें। अन्यथा, आप शायद उनका उपयोग कर रहे हैं।
माइक वुडहाउस

7

मुझे मिक्सिंस से परेशानी थी जिसमें इंस्टेंस मेथड्स और क्लास मेथड्स थे। यह कोड एक नौसिखिया की मदद कर सकता है:

module Displayable
  # instance methods here
  def display
    puts name
    self.class.increment_displays
  end
  def self.included(base)
    # This module method will be called automatically
    # after this module is included in a class.
    # We want to add the class methods to the class.
    base.extend Displayable::ClassMethods
  end
  module ClassMethods
    # class methods here
    def number_of_displays
      @number_of_displays # this is a class attribute
    end
    def increment_displays
      @number_of_displays += 1
    end
    def init_displays
      @number_of_displays = 0
    end
    # this module method will be called automatically
    # after this module is extended by a class.
    # We want to perform some initialization on a
    # class attribute.
    def self.extended(base)
      base.init_displays
    end
  end
end

class Person
  include Displayable
  def name; @name; end
  def initialize(name); @name=name; end
end

puts Person.number_of_displays # => 0
john = Person.new "John"
john.display # => John
puts Person.number_of_displays # => 1
jack = Person.new "Jack"
jack.display # => Jack
puts Person.number_of_displays # => 2

पहले, मैंने सोचा कि मैं उदाहरण के तरीकों और वर्ग विधियों दोनों के साथ मॉड्यूल कर सकता हूं बस यह करके:

module Displayable
  def display
    puts name
    self.class.increment_displays
  end
  def self.number_of_displays  # WRONG!
    @number_of_displays
  end
  [...]
end

दुर्भाग्य से, विधि नंबर_ऑफ_डिसप्ले को कभी भी शामिल या विस्तारित नहीं किया जाएगा क्योंकि यह एक "मॉड्यूल क्लास विधि" है। केवल "मॉड्यूल उदाहरण के तरीके" को एक वर्ग (उदाहरण के तरीकों) में शामिल किया जा सकता है या एक वर्ग (वर्ग विधियों के रूप में) में बढ़ाया जा सकता है। यही कारण है कि आपको अपने मिक्सिन की इंस्टेंस विधियों को एक मॉड्यूल में डालने की आवश्यकता है, और आपके मिक्सिन के क्लास के तरीकों को एक अन्य मॉड्यूल में (आप आमतौर पर क्लास के तरीकों को "क्लासमेथोड्स" सबमॉड्यूल में डालते हैं)। शामिल जादू पद्धति के लिए धन्यवाद , आप उदाहरण के तरीकों और कक्षा विधियों दोनों को केवल एक सरल "डिस्प्लेेबल" कॉल (जैसा कि ऊपर उदाहरण में दिखाया गया है) को शामिल करना आसान बना सकते हैं।

यह मिश्रण प्रत्येक प्रदर्शन को प्रति-वर्ग के आधार पर गिनेगा । काउंटर एक क्लास की विशेषता है, इसलिए प्रत्येक वर्ग का अपना होगा (आपका प्रोग्राम शायद विफल हो जाएगा यदि आप व्यक्तिगत वर्ग से एक नया वर्ग प्राप्त करते हैं क्योंकि व्युत्पन्न वर्ग के लिए @number_of_displays काउंटर को कभी भी प्रारंभ नहीं किया जाएगा)। आप इसे वैश्विक काउंटर बनाने के लिए @@ संख्या_of_displays द्वारा @number_of_displays को प्रतिस्थापित करना चाह सकते हैं । इस मामले में, प्रत्येक वर्ग पदानुक्रम का अपना काउंटर होगा। यदि आप एक वैश्विक और अद्वितीय काउंटर चाहते हैं, तो आपको संभवतः इसे एक मॉड्यूल विशेषता बनाना चाहिए।

यह सब निश्चित रूप से मेरे लिए सहज नहीं था जब मैंने रूबी के साथ शुरुआत की।

मैं अभी भी यह पता नहीं लगा सकता कि इन मिश्रण विधियों में से कुछ को कैसे निजी तौर पर या संरक्षित किया जा सकता है (केवल प्रदर्शन और नंबर_of_displays विधि को सार्वजनिक विधियों के रूप में शामिल किया जाना चाहिए)।


7

रेंज नोटेशन पर ध्यान दें।

(कम से कम, मैंने शुरू में जितना ध्यान दिया था उससे अधिक ध्यान दें !)

0..10 (दो डॉट्स) और 0...10(तीन डॉट्स) के बीच अंतर है ।

मैं रूबी को बहुत पसंद करता हूं। लेकिन यह डॉट-डॉट बनाम डॉट-डॉट-चीज़ मुझे परेशान करती है। मुझे लगता है कि इस तरह के एक सूक्ष्म दोहरे वाक्यविन्यास "सुविधा" है:

  • गलत करने के लिए आसान है, और
  • कोड पर नज़र रखते हुए अपनी आँखों से याद रखना आसान है

मेरे कार्यक्रमों में विनाशकारी ऑफ-बाय-वन कीड़े पैदा करने में सक्षम नहीं होना चाहिए।


1
से बहुत अलग for (i=0; i<max; i++)और नहींfor (i=0; i<=max; i++)
जी।

मैं यह जानने की कोशिश कर रहा था कि 0..10 और 0 ... 10 में क्या अंतर है।
लुइस डी उरका

6

मुझे लगता है कि " and" और " or" पर्ल के लिए नोड्स हैं, जो रूबी के अधिक स्पष्ट "माता-पिता" (सबसे प्रमुख अन्य स्मॉलटाक) है। उन दोनों में बहुत कम पूर्वता है (असाइनमेंट की तुलना में कम है, वास्तव में, जो कि जहां व्यवहार से आया है) की तुलना में &&और ||जो आप उपयोग कर रहे हैं वे ऑपरेटर हैं।

इसके बारे में पता करने के लिए अन्य चीजें तुरंत स्पष्ट नहीं हैं:

आप वास्तव में तरीकों / कार्यों को कॉल नहीं करते हैं, हालांकि यह थोड़े इस तरह दिखता है। इसके बजाय, जैसे कि स्मॉलटाक में, आप किसी वस्तु को संदेश भेजते हैं। तो method_missingवास्तव में अधिक पसंद है message_not_understood

some_object.do_something(args)

के बराबर है

some_object.send(:do_something, args) # note the :

प्रतीकों का बहुत व्यापक रूप से उपयोग किया जाता है। यह उन चीजों के साथ शुरू होता है :और वे तुरंत स्पष्ट नहीं होते हैं (अच्छी तरह से वे मेरे लिए नहीं थे) लेकिन इससे पहले कि आप उनके साथ बेहतर हो जाएं।

रूबी "बतख-टाइपिंग" पर बड़ी है, प्रिंसिपल का अनुसरण करते हुए कि "अगर यह एक बतख की तरह चलता है और बतख की तरह चलता है ..." जो बिना किसी स्पष्ट वंशानुक्रम या मिक्सिन संबंध के तरीकों के एक सामान्य उपसमूह के साथ वस्तुओं के अनौपचारिक प्रतिस्थापन की अनुमति देता है।


धन्यवाद। मुझे भेजने के तरीके से नफरत है ! आउच।
मिनीक्वार

1
@MiniQuark: यही मैं भेजने के तरीके के बारे में प्यार करता हूँ!
एंड्रयू ग्रिम

6

यदि आप एक सेटर (उर्फ म्यूटेटर) का उपयोग attr_writerया attr_accessor(या def foo=) घोषित करते हैं , तो इसे कक्षा के अंदर से कॉल करने से सावधान रहें। चूँकि चर को स्पष्ट रूप से घोषित किया जाता है, दुभाषिया को हमेशा foo = barविधि को कॉल करने के बजाय फू नाम के एक नए चर को घोषित करने के रूप में हल करना होता है self.foo=(bar)

class Thing
  attr_accessor :foo
  def initialize
    @foo = 1      # this sets @foo to 1
    self.foo = 2  # this sets @foo to 2
    foo = 3       # this does *not* set @foo
  end
end

puts Thing.new.foo #=> 2

यह Rails ActiveRecord ऑब्जेक्ट्स पर भी लागू होता है, जो डेटाबेस में फ़ील्ड्स के आधार पर एक्सेसर्स को परिभाषित करता है। चूंकि वे @ -स्टाइल उदाहरण चर भी नहीं हैं, उन मानों को व्यक्तिगत रूप से सेट करने का उचित तरीका है self.value = 123या self['value'] = 123


5

समय और दिनांक वर्ग के बीच अंतर को समझना। दोनों अलग-अलग हैं और रेल का उपयोग करते समय समस्याएँ पैदा की हैं। टाइम क्लास कभी-कभी मानक माणिक / रेल्स लाइब्रेरी में मौजूद अन्य टाइम क्लास पुस्तकालयों के साथ टकराव करता है। व्यक्तिगत रूप से मुझे यह समझने में बहुत समय लगा कि मेरे रेल एप्लिकेशन में क्या चल रहा था। बाद में, मुझे पता चला कि मैंने कब किया

Time.new

यह किसी ऐसे पुस्तकालय की बात कर रहा था, जिसके बारे में मुझे पता भी नहीं था।

क्षमा करें यदि मैं स्पष्ट नहीं हूं कि मैं वास्तव में क्या कहना चाहता हूं। यदि दूसरों को भी इसी तरह की समस्याओं का सामना करना पड़ा है, तो कृपया पुनः बताएं।


4

एक जो मुझे अतीत में पकड़ा गया है वह यह है कि नई पंक्ति वर्ण ( \n) अन्य से बच निकलने का क्रम — एकल उद्धरणों में तार द्वारा समर्थित नहीं है। बैकस्लैश खुद बच जाता है। उम्मीद के मुताबिक काम करने के लिए आपको दोहरे उद्धरण चिह्नों का उपयोग करना होगा।


1
और जो कि अन्य भाषा से अलग है?
रॉबर्ट गैंबल

जावा, एक के लिए। जावा में सिंगल कोट्स का उपयोग केवल एक ही चार्ट को संलग्न करने के लिए किया जा सकता है, स्ट्रिंग्स पर नहीं।
जॉन टॉपले

1
यह किसी भी भाषा को ध्यान में रखते हुए आपको स्ट्रिंग के लिए एकल उद्धरणों का उपयोग करने की अनुमति देता है, और यही कारण है कि वे ऐसा करते हैं।
सिंगापोलिम्मा

@ जॉन: सच है, लेकिन जावा में '\ n' अभी भी नया चरित्र होगा।
22

1
लेकिन जावा में एकल उद्धरण केवल टाइप चार के मूल्यों को बनाते हैं। तार नहीं। यही अंतर है।
jmucchiello

4
x = (true and false) # x is false

0 और '' सही हैं, जैसा आपने बताया।

आपके पास एक ही नाम से एक विधि और एक मॉड्यूल / वर्ग हो सकता है (जो समझ में आता है, क्योंकि विधि वास्तव में ऑब्जेक्ट में जुड़ जाती है और इस प्रकार इसका अपना नाम स्थान है)।

कोई एकाधिक वंशानुक्रम नहीं है, लेकिन अक्सर "मिक्सिन मॉड्यूल" का उपयोग कई वर्गों में सामान्य तरीकों को जोड़ने के लिए किया जाता है।


0 == true // argh c कंपाइलर मेरे दिमाग में फट रहा है !!
केनी डेसी

1
0 == रूबी में सच गलत है। यह 0 सच है, क्योंकि रूबी में एक वस्तु सही है। सी 0 में सिर्फ झूठ के रूप में एक ही प्रतिनिधित्व होता है।
जूल्स

रूबी में एक हालत में, केवल falseऔर nilझूठे हैं। अन्य सभी सच्चे मूल्य हैं।
रबप्रिंस

4

तरीकों को फिर से परिभाषित किया जा सकता है और जब तक आप कारण का पता नहीं लगाते हैं, तब तक यह एक मन-खरोंच बन सकता है। (निश्चित रूप से , यह त्रुटि संभवतः "कठिन" है यह पता लगाने के लिए कि जब रेल नियंत्रक पर एक रूबी को गलती से फिर से परिभाषित किया गया है! )

#demo.rb
class Demo

  def hello1
    p "Hello from first definition"
  end

  # ...lots of code here...
  # and you forget that you have already defined hello1

  def hello1
    p "Hello from second definition"
  end

end
Demo.new.hello1

Daud:

$ ruby demo.rb
=> "Hello from second definition"

लेकिन सक्षम चेतावनी के साथ इसे कॉल करें और आप इसका कारण देख सकते हैं:

$ ruby -w demo.rb
demo.rb:10: warning: method redefined; discarding old hello1
=> "Hello from second definition"

अगर मैं कर सकता था तो मैंने चेतावनी का उपयोग +100 किया।
एंड्रयू ग्रिम

3

मुझे लगता है कि इसका इस्तेमाल करना हमेशा अच्छा होता है। चीजों पर गति। चूंकि आकार लगभग हर चीज का समर्थन करता है और रूबी के पास गतिशील प्रकार होते हैं जिससे आप वास्तव में अजीब परिणाम प्राप्त कर सकते हैं। गलत तरीके से टाइप करने पर सूचित करें ... मैं इसके बजाय बहुत कुछ प्राप्त करूंगा। एक NoMethodError: अपरिभाषित विधि `लंबाई ', इसलिए मैं आमतौर पर रूबी में वस्तुओं पर आकार नहीं कहता।

मुझे एक से अधिक बार बिट।

यह भी याद रखें कि वस्तुओं में आईडी होते हैं, इसलिए मैं भ्रम से बचने के लिए चर कॉल आईडी या ऑब्जेक्ट_आईडी का उपयोग नहीं करने की कोशिश करता हूं। अगर मुझे एक यूजर ऑब्जेक्ट पर एक आईडी की आवश्यकता है तो इसे user_id जैसा कुछ कहना सबसे अच्छा है।

केवल मेरे दो सेंट्स


2

मैं माणिक के लिए नया हूं, और अपने पहले दौर में मैंने एक फ्लोट / स्ट्रिंग्स को एक पूर्णांक में बदलने के बारे में एक मुद्दा मारा। मैंने झांकियों के साथ शुरुआत की और f.to_int के रूप में सब कुछ कोडित किया । लेकिन जब मैंने जारी रखा और स्ट्रिंग्स के लिए एक ही विधि का उपयोग किया, तो मुझे एक वक्र फेंक दिया गया जब यह कार्यक्रम चलाने के लिए आया था।

वर्तमान में एक स्ट्रिंग में एक to_int विधि नहीं है , लेकिन तैरता है और ints करते हैं।

irb(main):003:0* str_val = '5.0'
=> "5.0"
irb(main):006:0> str_val.to_int
NoMethodError: undefined method `to_int' for "5.0":String
        from (irb):6
irb(main):005:0* str_val.to_i
=> 5


irb(main):007:0> float_val = 5.0
=> 5.0
irb(main):008:0> float_val.to_int
=> 5
irb(main):009:0> float_val.to_i
=> 5
irb(main):010:0>

मनमाना कोष्ठक मुझे पहले भी फेंक दिया। मैंने कुछ कोड देखे और कुछ बिना। मुझे यह महसूस करने में थोड़ी देर लगी कि या तो शैलियों को स्वीकार किया जाता है।


2

मोनकुट की प्रतिक्रिया से संबंधित, रूबी के to_fooतरीकों से संकेत मिलता है कि वे कितना सख्त रूपांतरण करेंगे।

जैसे छोटे लोग to_i, to_sइसे आलसी बताते हैं, और उन्हें लक्ष्य प्रकार में परिवर्तित करते हैं, भले ही वे उस प्रारूप में सटीक रूप से प्रतिनिधित्व करने में सक्षम न हों। उदाहरण के लिए:

"10".to_i == 10
:foo.to_s == "foo"

लंबे समय तक स्पष्ट कार्यों की तरह to_int, to_sमतलब है कि वस्तु देशी रूप उस प्रकार का डेटा के रूप में प्रतिनिधित्व किया जा सकता है। उदाहरण के लिए, Rationalवर्ग सभी परिमेय संख्याओं का प्रतिनिधित्व करता है, इसलिए इसे सीधे कॉल करके एक Fixnum (या Bignum) पूर्णांक के रूप में दर्शाया जा सकता है to_int

Rational(20,4).to_int == 5

यदि आप अधिक लंबी विधि नहीं कह सकते हैं, तो इसका मतलब है कि वस्तु को उस प्रकार से मूल रूप से प्रस्तुत नहीं किया जा सकता है।

इसलिए मूल रूप से, परिवर्तित करते समय, यदि आप विधि नामों से आलसी हैं, तो रूबी रूपांतरण के साथ आलसी हो जाएगी।


1
क्या "आलसी" यहाँ सही शब्द है?
एंड्रयू ग्रिम


1

रूबी हैश पर ओवररिएशन किसी विशेष क्रम में होने की गारंटी नहीं है। (यह एक बग नहीं है, यह एक सुविधा है)

Hash#sort यदि आपको किसी विशेष आदेश की आवश्यकता हो तो उपयोगी है।

संबंधित प्रश्न: रूबी की 1000 हैश की कुंजी और मूल्य जोड़े हमेशा एक विशेष क्रम में क्यों हैं?


4
यह 1.9 के रूप में मान्य नहीं है: "रूबी 1.9 में, हालांकि, रूबी प्रोग्रामिंग भाषा से हैश तत्वों को उनके सम्मिलन क्रम में प्रसारित किया जाता है"
13zgür

0

इसने मुझे एक बार पागल कर दिया था:

1/2 == 0.5 #=> false
1/2 == 0   #=> true

मेरा मानना ​​है कि यह जावा, सी और सी ++ में ठीक उसी तरह का व्यवहार करेगा।
लैरी

यह मज़ेदार है, मैंने इसके बारे में सोचा भी नहीं था, लेकिन अगर आप irb खोलते हैं और यह कोशिश करते हैं, तो यह समझ में आता है: तो (1/2) एक Fixnum है और (0.5) एक Float है। और हम जानते हैं कि Fixnim! = फ्लोट।
डेमिट्री

2
@DemitryT मुझे लगता है कि इसका सरल कारण यह है कि यह 1/2मूल्यांकन 0करता है, जो समान 0.5प्रकार का नहीं है। हालाँकि, Rational(1, 2) == 0.5और 1.0 == 1,।
मैक्स नानसी

यहाँ सार्वभौमिक भाषा हिचकी। यह रूबी के लिए नया कुछ है और प्रोग्रामिंग को जानना चाहिए।
dtc

0
1..5.each {|x| puts x}

काम नहीं करता है। आपको रेंज को कोष्ठक में रखना होगा, जैसे

(1..5).each {|x| puts x}

इसलिए यह नहीं लगता कि आप फोन कर रहे हैं 5.each। मुझे लगता है कि यह एक पूर्ववर्ती मुद्दा है, जैसे x = true and falseगोचरा।


मैं इसके बजाय कोष्ठक कहूंगा। दूसरे, यदि कोई कोड रिटर्न वैल्यू / पूर्ववर्ती समस्या होने जैसा दिखता है, तो इसे वैसे भी कोष्ठकों से घिरा होना चाहिए। तो, मेरे लिए, इस "गोचा" पर कुछ खास नहीं है। आप हर कॉम्बिनेशन "गोचैस" लिख सकते हैं, हालांकि यह समय की बर्बादी होगी। सच कहूँ, भले ही आप इस पर अपेक्षित परिणाम था, मैं अभी भी कोष्ठक के साथ आसपास रहना पसंद करेंगे।
.zgür
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.