如何在 Ruby 中使用模块扩展浮点和数组类
Posted
技术标签:
【中文标题】如何在 Ruby 中使用模块扩展浮点和数组类【英文标题】:How to extend Float and Array classes using modules in Ruby 【发布时间】:2021-01-16 11:08:34 【问题描述】:在为模块中的 Float 和 Array 类定义新方法时,我发现 方法不被承认为方法,尽管该模块被包含在内。我只是成为 熟悉 Ruby 中模块的使用,因此我将不胜感激。代码如下:
#! /usr/bin/env ruby
module NewMath
include Math
puts("Hello from NewMath")
class Array
def mean
raise Exception, "#self should be a uniform array of numbers" if
!hasElementsOfUniformType?( self) || !self.first.is_a?(Numeric)
sum = inject(&:+)
return (self.first.is_a?(Integer)) ? sum / size : sum / size.to_f
end
def standardDeviation
raise Exception, "#self should be a uniform array of numbers" if \
!hasElementsOfUniformType?( self) || !self.first.is_a?(Numeric)
raise ArgumentError, "#self should be an array of more than 1 numbers" if \
self.size < 2
mn = self.mean
sumOfDeviationSqr = self.map |x| x.to_f - mn.to_f \
.map |deviation| deviation * deviation .reduce(:+) / (size - 1).to_f
return Math.sqrt(sumOfDeviationSqr)
end
end
class Integer
def notToExceed( limit)
return (self > limit) ? limit : self
end
end
class Float
def constrainAndFormat(low:, high:, decimalPlaces:)
raise Exception, "low: #low should be a Float" if !low.is_a?(Float)
raise Exception, "high: #high should be a Float value > #lo" \
if !high.is_a?(Float) || high < low
raise Exception, "decimalPlaces: #decimalPlaces should be a positive integer" \
if (decimalPlaces < 1)
item = (self > high) ? high : (self < low) ? low : self
factor = 1.upto(decimalPlaces).map |i| 10.to_f .reduce(:*)
truncate = (item * factor).to_i.to_f
return truncate / factor
end
end
end
include NewMath
print("\n Array's public instance methods: #Array.public_instance_methods")
print
print("\n Array's included modules: #Array.included_modules")
print
list = []
100.times.each do
list << rand(1..100)
end
print("\n list = #list\n")
print("\n s.d. = #list.standardDeviation\n")
a = list.mean
print("\n mean = #a\n")
print("\n Float's public instance methods: #Float.public_instance_methods")
l = 1.0 /3.0
print("\n l = #l , #l.constrainAndFormat(low: 0.0, high:2.0, decimalPlaces:4)")
************************* end of code *******************************************
Mean, standardDeviation, and constrainAndFormat are undefined. Array's list of public
instance methods excludes standardDeviation.
Array 的公共实例方法:[:to_h, :include?, :at, :fetch, :last, :union, :difference, :push, :append, :pop, :shift, :unshift, :each_index, : join, :rotate, :rotate!, :sort!, :sort_by!, :collect!, :map!, :select!, :filter!, :keep_if, :values_at, :delete_at, :delete_if, :reject!, :转置、:fill、:assoc、:rassoc、:uniq!、:compact、:compact!、:flatten、:flatten!、:shuffle!、:shuffle、:*、:+、:permutation、:&、:repeated_permutation , :combination, :sample, :repeated_combination, :product, :bsearch, :-, :sort, :bsearch_index, :count, :find_index, :select, :filter, :reject, :collect, :map, :first, : all?, :any?, :one?, :none?, :reverse_each, :zip, :take, :take_while, :drop, :drop_while, :cycle, :sum, :uniq, :|, :insert, :, :id, :instance_exec, :!=, :instance_eval, :发送]
Array 包含的模块:[Enumerable, NewMath, Math, Kernel]
列表 = [90, 61, 39, 63, 17, 39, 26, 9, 91, 69, 67, 39, 33, 13, 63, 68, 100, 58, 25, 3, 37, 28, 56, 43 , 100, 43, 3, 3, 25, 97, 56, 20, 86, 25, 21, 60, 8, 20, 87, 32, 1, 97, 52, 51, 83, 86, 57, 55, 91 , 16, 49, 83, 46, 82, 58, 56, 40, 22, 8, 60, 91, 5, 50, 11, 57, 27, 53, 39, 83, 12, 90, 92, 61, 83 , 31, 87, 63, 97, 76, 66, 58, 24, 8, 82, 17, 44, 76, 43, 71, 29, 95, 34, 22, 54, 90, 5, 11, 98, 26 , 79]
回溯(最近一次通话最后):
./newTesting.rb:63:in <main>': undefined method
standardDeviation' for #Array:0x00007fdd9514c768 (NoMethodError)
【问题讨论】:
【参考方案1】:您已经定义了三个类,NewMath::Array
、NewMath::Integer
和 NewMath::Float
。
然后,您已将NewMath
模块包含到main
(***范围)中。 include
做了一些事情,但“合并具有相同名称的类”不是其中之一。它不会“合并”Array
与 NewMath::Array
。
你想要做的可能是:
module NewMath
module Array
def foo
puts "foo"
end
end
end
Array.include(NewMath::Array)
[].foo # prints "foo"
很高兴你尝试这样做 b/c 这保留了所有者:
pry(main)> [].method(:foo).owner
=> NewMath::Array
这使得代码很容易找到。这与直接打开类相反:
# this could be in any file, anywhere
class Array
def bar
puts "bar"
end
end
[].method(:bar).owner # => Array (gives you no indication where it came from)
【讨论】:
以上是关于如何在 Ruby 中使用模块扩展浮点和数组类的主要内容,如果未能解决你的问题,请参考以下文章
serversocket 类如何在同一个端口上服务多个客户端连接?
idea java中Jformdesigner自动生成的类如何在public static void main(String[] args)}中引用