मैं Enumerable#each और Enumerable#map के लिए विधियां बनाने की कोशिश कर रहा हूं, जिन्हें my_each और my_map कहा जाता है।

लेकिन एक समस्या है जब मैं my_each से my_map मानचित्र में एक ब्लॉक में आने की कोशिश करता हूं, क्या कोई मेरी मदद कर सकता है?

जब मैं my_each को my_map के अंदर केवल each के लिए बदलता हूं, तो यह काम करता है

module Enumerable
  def my_each
   return self.to_enum :my_each unless block_given?
       for i in 0..self.length - 1
           yield(self[i])
       end
       return self
  end

   def my_map(proc=nil)
       return_array = Array.new
       return self.to_enum :my_map if !block_given? && proc.nil?
       self.my_each do |i|
           return_array.push(proc.call(i)) unless proc.nil?
           return_array.push(yield(i)) if block_given? && proc.nil?
       end
       return_array
   end
end



array = [1, 2, 3, 4, 5]

puts '*** my_each ***'
array.my_each do |num|
  puts num * num
end

   puts '*** my_map ***'
puts "#{((1..4).my_map { |i| i * i })} "
puts "#{(1..4).my_map.to_a} "
puts "#{([1, 2, 3, 4].my_map { |i| i * i })} "
puts "#{[1, 2, 3, 4].my_map.to_a}\n\n\n"

इसे सामान्य map विधि के रूप में काम करना चाहिए, लेकिन यह मुझे यह फेंकता है:

undefined method `length' for 1..4:Range
1
Feber Castellon 3 नवम्बर 2019, 18:45

1 उत्तर

सबसे बढ़िया उत्तर

ऐसा इसलिए है क्योंकि आप एक रेंज ऑब्जेक्ट में my_each का आह्वान कर रहे हैं। और आपका कोड देखकर, रेंज वर्ग पर परिभाषित कोई विधि my_each नहीं है।

चूंकि my_map रिसीवर में to_a को स्पष्ट रूप से कॉल नहीं करता है, तो आप my_map परिभाषा के भीतर "जैसा है" ऑब्जेक्ट का उपयोग कर रहे हैं:

def my_map(proc=nil)
  ...
  self.my_each do |i|
    ...
  end
  ...
end

आप रिसीवर को एक सरणी में बदल सकते हैं और त्रुटि से छुटकारा पा सकते हैं:

puts (1..4).to_a.my_map { |i| i * i }
# 1
# 4
# 9
# 16
2
Sebastian Palma 3 नवम्बर 2019, 18:52