在Ruby中编写这个的正确方法是什么?

时间:2017-04-26 01:21:45

标签: ruby

我需要写几个方法:value(x)zero(a,b,e)area(a,b)derivative(x)

class Funkcja

    def initialize(funkcja)
        @funkcja = funkcja
    end

    def value(x)
        @funkcja.call(x)
    end
end

这个类必须处理块,这是来自Proc

的对象

这是我创建新对象的方式

f = Funkcja.new (Proc.new{|x| x*x*Math.sin(x)})

什么是正确的方式和Ruby风格(如果没有请告诉我,我 Ruby中的新手)正确Funkcja.new (Proc.new x)和 初始化@funkcja = funkcja

def zero(a, b, eps)
      x = (a+b)/2.0
      val = value(x)

      if val >= -eps and val <= eps
         x
      else
        left = value(a)
        rigth = value(b)
        if left < 0 and val > 0
            zero(a,x,eps)
        elsif left > 0 and val < 0
            zero(a,x,eps)
        elsif rigth > 0 and val < 0
            zero(x,b,eps)
        elsif rigth < 0 and val > 0
            zero(x,b,eps)
        elsif value == 0
            x
        else
            nil
        end
      end
  end

  def area(a,b)
    pole = 0
    while a < b
        if (self.value(a) > self.value( a + 0.00001))
            pole = pole + (self.value( a) * 0.00001)
        else
            pole = pole + (self.value( a + 0.00001) * 0.00001 )
        end
        a += 0.00001
    end
    pole
  end

  def derivative(x)
    eps = 0.00000001
    return (self.value(x) - self.value(x - eps))/eps
  end

面积是abOX之间的计算区域,零是找到的地方 F (x)=0导数计算为点的导数。

2 个答案:

答案 0 :(得分:1)

非惯用的主要是:

f = Funkcja.new (Proc.new{|x| x*x*Math.sin(x)})

更正常的是这样做:

f = Funkcja.new { |x| x*x*Math.sin(x) }

这是一个普通的块,你可以像往常一样在多行之间拆分:

f = Funkcja.new do |x|
  x*x*Math.sin(x)
end

但是,这不适用于您的initialize定义,而这是因为一个小细节。您只需要将def initialize(funkcja)更改为def initialize(&funkja) - 这会将传递的块转换为可以分配给变量的过程,使用call等等:

def initialize(&funjka)
  @funkja = funkja
end

另一种做同样事情的方法是:

def initialize
  @funkja = yield
end

除此之外,你的代码似乎很好用另一个明显的非惯用的东西,你使用self.value。除非您使用的是setter方法(即self),否则self.value =是不必要的,您不在此处。

答案 1 :(得分:0)

这里有一个想法,让你的一种方法适应更多的Ruby风格:

def area(a,b)
  pole = 0

  while a < b
    if (yield(a) > yield(a + 0.00001))
      pole = pole + (yield(a) * 0.00001)        
    else
      pole = pole + (yield(a + 0.00001) * 0.00001)
    end

    a += 0.00001
  end

  pole
end

您可以这样使用它:

area(a, b) do |a|
  a ** 2
end

现在处理Proc对象是一回事,没问题,方法调用附加块的do ... end方法默认生成那些。它非常 Ruby在Proc本身上放置额外的方法。我在这里看不到任何可以通过在一个简单的模块中定义这些内容而被覆盖的内容:

module CalculationModule  
  def area(a, b)
    # ... Implementation
  end

  extend self
end

通过这种方式,您可以使用CalculationModule.area等方法,或者始终include将其用于其他类或模块,并像area一样使用它们。