如何在要在Ruby哈希中打印的值内获取键名

时间:2019-06-17 22:31:07

标签: ruby lambda ruby-hash

我正在创建一个包含lambda作为Ruby中值的哈希。我想访问lambda中的键名。

散列是匿名函数(lambda)的集合,这些匿名函数接受输入并执行特定任务。因此,我正在制作一个绘制形状的哈希,因此哈希中的键是诸如圆形,正方形之类的形状名称,并且该键的值是一个lambda,它接受输入并执行一些任务,从而导致绘制形状。 因此,在这里我要在lambda中打印形状的名称,即键。

真实示例:

MARKER_TYPES = {
        # Default type is circle
        # Stroke width is set to 1
        nil: ->(draw, x, y, fill_color, border_color, size) {
          draw.stroke Rubyplot::Color::COLOR_INDEX[border_color]
          draw.fill Rubyplot::Color::COLOR_INDEX[fill_color]
          draw.circle(x,y, x + size,y)
        },
        circle: ->(draw, x, y, fill_color, border_color, size) {
          draw.stroke Rubyplot::Color::COLOR_INDEX[border_color]
          draw.fill Rubyplot::Color::COLOR_INDEX[fill_color]
          draw.circle(x,y, x + size,y)
        },
        plus: ->(draw, x, y, fill_color, border_color, size) {
          # size is length of one line
          draw.stroke Rubyplot::Color::COLOR_INDEX[fill_color]
          draw.line(x - size/2, y, x + size/2, y)
          draw.line(x, y - size/2, x, y + size/2)
        },
        dot: ->(draw, x, y, fill_color, border_color, size) {
          # Dot is a circle of size 5 pixels
          # size is kept 5 to make it visible, ideally it should be 1
          # which is the smallest displayable size
          draw.fill Rubyplot::Color::COLOR_INDEX[fill_color]
          draw.circle(x,y, x + 5,y)
        },
        asterisk: ->(draw, x, y, fill_color, border_color, size) {
          # Looks like a five sided star
          raise NotImplementedError, "marker #{self} has not yet been implemented"
        }
}

哈希包含大约40个这样的键,值对。

所需的输出为marker star has not yet been implemented

一个简单的例子:

HASH = {
  key1: ->(x) {
   puts('Number of key1 = ' + x.to_s) 
  }
}

我不想使用硬编码key1来获取键的名称,该键的名称是lambda,因为哈希中有很多lambda。

key1替换#{self}会打印类而不是键的名称。

2 个答案:

答案 0 :(得分:1)

我不认为这可以做到。哈希是键和值的集合。键是唯一的,值不是。您要询问的值是键所属的值(在这种情况下为lambda,但这并不重要)。我可以是一个,一个也可以不多个。值无法“知道”。询问哈希,而不是值。

答案 1 :(得分:0)

您正在尝试在Ruby中重新实现面向对象的编程。不需要,一切都是Ruby中的对象!

您可以删除所有重复的代码,lambda和复杂的哈希逻辑:

class MarkerType
  attr_reader :name
  def initialize(name, &block)
    @name = name
    @block = block
  end

  def draw(*params)
    if @block
      @block.call(*params)
    else
      puts "Marker #{name} has not been implemented yet!"
    end
  end
end

square = MarkerType.new 'square' do |size=5|
  puts "Draw a square with size : #{size}"
end

square.draw
# => Draw a square with size : 5


asterisk = MarkerType.new 'asterisk'
asterisk.draw
# => Marker asterisk has not been implemented yet!