加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Ruby – method_missing

发布时间:2020-12-17 01:54:05 所属栏目:百科 来源:网络整理
导读:我正在尝试实现一个用于将$转换为其他货币的method_missing,就像5.dollars产生5,5.yen将产生0.065 5.euro 6.56等等.我现在可以做.现在我需要实现它,但是以5.dollars.in(:yen)为例. 这就是我现在所拥有的: class Numeric @@currencies = {'yen' = 0.013,'eu
我正在尝试实现一个用于将$转换为其他货币的method_missing,就像5.dollars产生5,5.yen将产生0.065 5.euro 6.56等等.我现在可以做.现在我需要实现它,但是以5.dollars.in(:yen)为例.

这就是我现在所拥有的:

class Numeric
  @@currencies = {'yen' => 0.013,'euro' => 1.292,'rupee' => 0.019}
  def method_missing(method_id)
    singular_currency = method_id.to_s.gsub( /s$/,'')
    if @@currencies.has_key?(singular_currency)
      self * @@currencies[singular_currency]
    else
      super
    end
  end
end

任何人都可以解释我怎么做到这一点?

PS:我宁愿你不给我代码,而是解释,所以我可以自己确定它是如何完成的.

解决方法

也许这会有更多的帮助.这是一个有效的例子(注意,我希望你有ActiveSupport [Rails的一部分]和Ruby 1.9.2):

require 'rubygems'

# This is allowing us to do the `pluralize` calls below
require 'active_support/inflector'

module Currency
  CONVERSION_TABLE = { dollars: { dollars: 1,euros: 0.75 },euros: { dollars: 1.3333334,euros: 1 } }.freeze
  attr_accessor :currency

  def method_missing(method_name,*args,&block)
    # standardize on pluralized currency names internally so both singular
    # and plural methods are handled
    method_name = method_name.to_s.pluralize.to_sym

    # Use the "from" keys in the conversion table to verify this is a valid 
    # source currency
    if CONVERSION_TABLE.key?(method_name)
      @currency = method_name
      self # return self so a call to `1.dollar` returns `1` and not `:dollars`
    else
      super
    end
  end

  # Convert `self` from type of `@currency` to type of `destination_currency`,mark the result with
  # the appropriate currency type,and return. Example:
  def to(destination_currency)
    # Again,standardize on plural currency names internally
    destination_currency = destination_currency.to_s.pluralize.to_sym

    # Do some sanity checking
    raise UnspecifiedSourceCurrency unless defined?(@currency)
    raise UnsupportedDestinationCurrency unless CONVERSION_TABLE.key?(destination_currency)

    # Do the actual conversion,and round for sanity,though a better
    # option would be to use BigDecimal which is more suited to handling money
    result = (self * CONVERSION_TABLE[@currency][destination_currency]).round(2)

    # note that this is setting @currency through the accessor that
    # was created by calling `attr_accessor :currency` above
    result.currency = destination_currency
    result
  end
end

class Numeric
  # Take all the functionality from Currency and mix it into Numeric
  # 
  # Normally this would help us encapsulate,but right now it's just making
  # for cleaner reading. My original example contained more encapsulation
  # that avoided littering the Numeric clas,but it's harder for a beginner
  # to understand. For now,just start here and you will learn more later.
  include Currency
end

p 5.euros.to(:dollars)                #=> 6.67
p 0.25.dollars.to(:euro)              #=> 0.19
p 1.dollar.to(:euros).to(:dollar)     #=> 1.0

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读