LoginSignup
0
0

More than 1 year has passed since last update.

はじめに

移植やってます。
( from python 3.7 to ruby 2.7 )

辞書クラスの拡張 (Python)

    def __setitem__(self, key, value):
        if isinstance(value, float):
            value = int(round(value))
        elif not isinstance(value, int):
            raise PyteomicsError('Only integers allowed as values in '
                                 'Composition, got {}.'.format(type(value).__name__))
        if value:  # reject 0's
            super(BasicComposition, self).__setitem__(key, value)
        elif key in self:
            del self[key]

辞書クラスを継承したコンポクラスを設定します。
ここでは、値をfloatもしくはintで受け取るのですが、roundし整数で保管します。
また、値が0の場合、そのキーを削除しています。

Pythonの場合、特殊メソッド(__getitem__, __setitem__, __delitem__等)を使用してコンテナー型(list/tuple/dict)を拡張することができます。

独習Python 515p

失敗 (Ruby)

  def __setitem__(key, value)
    if value.instance_of?(Float)
      value = value.round
    elsif value.instance_of?(Integer).!
      raise PyteomicsError.new("Only integers allowed as values in Composition, got #{value.class}.")
    end
    if value != 0 # reject 0's
      self[key] = value       # 失敗
    elsif self.include?(key)
      self.delete(key)
    end
  end

  def []=(...)
    __setitem__(...)
  end

これですと、[]=が無限ループとなってしまいます。

成功 (Ruby)

  def __setitem__(key, value)
    if value.instance_of?(Float)
      value = value.round
    elsif value.instance_of?(Integer).!
      raise PyteomicsError.new("Only integers allowed as values in Composition, got #{value.class}.")
    end
    if value != 0 # reject 0's
      self.merge!({key => value})  # 成功
    elsif self.include?(key)
      self.delete(key)
    end
  end

  def []=(...)
    __setitem__(...)
  end

[]=を使用せずに、値を変更できればいいわけです。
もっといい書き方があるかもしれませんが。

メモ

  • Python の 辞書クラスの拡張 を学習した
  • 百里を行く者は九十里を半ばとす
0
0
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0