Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby:许多具有相似方法命名模式的相关对象。如何将它们映射到标准化方法_Ruby - Fatal编程技术网

Ruby:许多具有相似方法命名模式的相关对象。如何将它们映射到标准化方法

Ruby:许多具有相似方法命名模式的相关对象。如何将它们映射到标准化方法,ruby,Ruby,我正在开发一个程序,该程序接收来自API的响应,该API表示来自数据库的“歌曲”。这些响应作为Struct对象到达我的程序中,它们的结构略有不同,这取决于它们从哪个表中提取 例如,从“track”表中提取的歌曲对象如下所示: song_1 = <struct Song track_artist="Michael Jackson", track_title="Billie Jean"> song_2 = <struct Song license_artist="Michael

我正在开发一个程序,该程序接收来自API的响应,该API表示来自数据库的“歌曲”。这些响应作为Struct对象到达我的程序中,它们的结构略有不同,这取决于它们从哪个表中提取

例如,从“track”表中提取的歌曲对象如下所示:

song_1 = <struct Song track_artist="Michael Jackson", track_title="Billie Jean"> 
song_2 = <struct Song license_artist="Michael Jackson", license_title="Billie Jean">
{ track_artist:   artist,
  track_title:    title,
  license_artist: artist,
  license_title:  title }

这似乎有点过分了。最好的方法是什么?

您可以使用缺少的方法

module Unifier
  def method_missing(name, *args, &block)
    meth = public_methods.find { |m| m[/_#{name}/] }
    meth ? send(meth, *args, *block) : super
  end

  def respond_to_missing?(method_name, include_private = false)
    public_methods.any? { |m| m[/_#{method_name}/] } || super
  end
end

class A
  include Unifier
  attr_reader :artist_name
  def initialize
    @artist_name = 123
  end
end

a = A.new
a.respond_to?(:name) # => true
a.name # => 123
a.respond_to?(:title) # => false
a.title # => undefined method `title' for #<A:0x007fb3f4054330 @artist_name=123> (NoMethodError)
如果您只能处理该类的对象,则可以动态地对其进行修补

# We get objects of licence_struct class
licence_struct = Struct.new(:license_artist, :license_title)
song_2 = licence_struct.new('Michael Jackson', 'Billie Jean')
song_3 = licence_struct.new('Michael Jackson', 'Black of White')


def process_song(song)
  puts "Song #{song} patched - #{song.respond_to?(:artist)}"
  "#{song.artist} - #{song.title}"
rescue NoMethodError => err
  # If we don't have methods on our struct - patch it
  # If after patching object still dont respond to our method - throw exception
  patch_object_from_error(err) ? retry : raise(err)
end

def patch_object_from_error(error)
  receiver = error.receiver
  receiver.class.class_exec { include Unifier }
  meth = error.message.match(/undefined method `(\S+)'/)[1].to_sym
  receiver.respond_to?(meth)
end

puts process_song(song_2)
# => Song #<struct license_artist="Michael Jackson", license_title="Billie Jean"> patched - false
# after retry
# => Song #<struct license_artist="Michael Jackson", license_title="Billie Jean"> patched - true
# => Michael Jackson - Billie Jean
puts process_song(song_3)
# dont need retry - class already patched
# => Song #<struct license_artist="Michael Jackson", license_title="Black of White"> patched - true
# => Michael Jackson - Black of White
#我们得到许可证结构类的对象
许可证结构=结构新(:许可证艺术家,:许可证标题)
song_2=新的许可证结构('Michael Jackson'、'Billie Jean')
song_3=许可证结构新('Michael Jackson'、'Black of White')
def过程_宋(宋)
将“Song{Song}打补丁-{Song.Response_to?(:艺术家)}”
“{song.Artister}-{song.title}”
rescue NoMethodError=>错误
#如果我们的结构上没有方法,请修补它
#如果在修补对象之后仍然没有响应我们的方法-抛出异常
从错误(err)修补对象?重试:引发(错误)
结束
def patch_对象_from_错误(错误)
接收器=错误。接收器
receiver.class.class_exec{include Unifier}
meth=error.message.match(/undefined method`(\S+)/)[1]。到\u sym
接受者。回应?(冰毒)
结束
将进程放入歌曲(歌曲2)
#=>歌曲#修补-错误
#重试后
#=>歌曲#修补-正确
#=>迈克尔·杰克逊-比利·琼
将进程放入歌曲(歌曲3)
#不需要重试-类已修补
#=>歌曲#修补-正确
#=>迈克尔杰克逊-黑白相间

您可以为此使用缺少的方法

module Unifier
  def method_missing(name, *args, &block)
    meth = public_methods.find { |m| m[/_#{name}/] }
    meth ? send(meth, *args, *block) : super
  end

  def respond_to_missing?(method_name, include_private = false)
    public_methods.any? { |m| m[/_#{method_name}/] } || super
  end
end

class A
  include Unifier
  attr_reader :artist_name
  def initialize
    @artist_name = 123
  end
end

a = A.new
a.respond_to?(:name) # => true
a.name # => 123
a.respond_to?(:title) # => false
a.title # => undefined method `title' for #<A:0x007fb3f4054330 @artist_name=123> (NoMethodError)
如果您只能处理该类的对象,则可以动态地对其进行修补

# We get objects of licence_struct class
licence_struct = Struct.new(:license_artist, :license_title)
song_2 = licence_struct.new('Michael Jackson', 'Billie Jean')
song_3 = licence_struct.new('Michael Jackson', 'Black of White')


def process_song(song)
  puts "Song #{song} patched - #{song.respond_to?(:artist)}"
  "#{song.artist} - #{song.title}"
rescue NoMethodError => err
  # If we don't have methods on our struct - patch it
  # If after patching object still dont respond to our method - throw exception
  patch_object_from_error(err) ? retry : raise(err)
end

def patch_object_from_error(error)
  receiver = error.receiver
  receiver.class.class_exec { include Unifier }
  meth = error.message.match(/undefined method `(\S+)'/)[1].to_sym
  receiver.respond_to?(meth)
end

puts process_song(song_2)
# => Song #<struct license_artist="Michael Jackson", license_title="Billie Jean"> patched - false
# after retry
# => Song #<struct license_artist="Michael Jackson", license_title="Billie Jean"> patched - true
# => Michael Jackson - Billie Jean
puts process_song(song_3)
# dont need retry - class already patched
# => Song #<struct license_artist="Michael Jackson", license_title="Black of White"> patched - true
# => Michael Jackson - Black of White
#我们得到许可证结构类的对象
许可证结构=结构新(:许可证艺术家,:许可证标题)
song_2=新的许可证结构('Michael Jackson'、'Billie Jean')
song_3=许可证结构新('Michael Jackson'、'Black of White')
def过程_宋(宋)
将“Song{Song}打补丁-{Song.Response_to?(:艺术家)}”
“{song.Artister}-{song.title}”
rescue NoMethodError=>错误
#如果我们的结构上没有方法,请修补它
#如果在修补对象之后仍然没有响应我们的方法-抛出异常
从错误(err)修补对象?重试:引发(错误)
结束
def patch_对象_from_错误(错误)
接收器=错误。接收器
receiver.class.class_exec{include Unifier}
meth=error.message.match(/undefined method`(\S+)/)[1]。到\u sym
接受者。回应?(冰毒)
结束
将进程放入歌曲(歌曲2)
#=>歌曲#修补-错误
#重试后
#=>歌曲#修补-正确
#=>迈克尔·杰克逊-比利·琼
将进程放入歌曲(歌曲3)
#不需要重试-类已修补
#=>歌曲#修补-正确
#=>迈克尔杰克逊-黑白相间

您能否扩展您的解决方案,以展示它将如何与有疑问的
结构一起工作?因为它目前没有提供该解决方案将如何运行的完整信息help@WandMaker展开解决方案您能否展开您的解决方案,以显示它将如何与有疑问的
Struct
一起工作?因为它目前没有提供该解决方案将如何运行的完整信息help@WandMaker展开解决方案能否共享显示如何定义结构
Song
的代码?我假设您正在从数据库中提取字符串。也许是JSON字符串?请编辑以准确识别字符串是什么。在第一个示例中,字符串是否为
“您能否共享显示如何定义struct
Song
的代码?我假设您正在从数据库中提取字符串。也许是JSON字符串?请编辑以准确识别字符串是什么。在第一个示例中,是字符串
'