Как получить имя ключа внутри значения для печати внутри хеша Ruby - PullRequest
0 голосов
/ 18 июня 2019

Я создаю хеш, содержащий лямбды в качестве значения в Ruby. Я хочу получить доступ к имени ключа в лямбде.

Хеш - это коллекция анонимных функций (лямбда-выражений), которые принимают входные данные и выполняют определенную задачу. Итак, я делаю хеш, который рисует форму, и поэтому ключи в хэше - это имена форм, такие как круг, квадрат, а значение для этого ключа - лямбда, которая принимает входные данные и выполняет некоторую задачу, которая приводит к нарисованной форме , Итак, здесь я хочу напечатать название фигуры, то есть ключ, в лямбде.

Реальный пример:

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 Я хочу получить имя ключа в значении, которое является лямбда-выражением, поскольку в хэше много лямбд.

Замена key1 на #{self} печатает класс, а не имя ключа.

Ответы [ 2 ]

1 голос
/ 18 июня 2019

Я не думаю, что это можно сделать. Хеш - это набор ключей и значений. Ключи уникальны, а значения - нет. Вы спрашиваете значение (лямбда в данном случае, но это не имеет большого значения) к какому ключу оно принадлежит. Я мог быть один, никто или много; нет значения для значения "знать". Задайте хеш, а не значение.

0 голосов
/ 18 июня 2019

Вы пытаетесь повторно реализовать объектно-ориентированное программирование в Ruby. В этом нет необходимости, в Ruby все является объектом!

Вы можете удалить весь дублированный код, лямбды и сложную хэш-логику:

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!
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...