Ruby元编程“深度”

时间:2018-09-11 19:27:51

标签: ruby metaprogramming

我开始学习Ruby中的元编程,并且(我认为)我了解如何添加实例方法和变量,但前提是一次只能传递一个。例如,test.new_value = true。我想知道如何用两个点test.like.this向命令添加额外的深度。例如:

class StackOverflow
  def initialize(name)
    @name = name
  end

  def method_missing(argument, *args)
    argument = argument.to_s

    if argument =~ /failing/
      puts 'FOUND FAILING'
      puts argument
      puts args[0]
      return
    end

    if argument =~ /this_test_is/
      puts 'FOUND THIS TEST IS'
      puts argument
      puts args[0]
      return
    end

    if argument =~ /this_works=/
      instance_variable_set("@#{argument.to_s.chop}", args[0])
      return
    else
      return instance_variable_get("@#{argument}").to_s
    end
  end
end

test = StackOverflow.new("post")
test.this_works = true
puts "IT WORKED: " + test.this_works
test.this_test_is.failing

提供以下输出:

ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-linux]

IT WORKED: true
FOUND THIS TEST IS
this_test_is

undefined method `failing' for nil:NilClass
(repl):44:in `<main>'

我想要做的是将其视为变量和值对。我想知道这两种情况下如何做:

A:识别this_test_is并将其作为变量存储在字符串中(或符号可以)failing

B:将failing识别为变量,如果我看到this_test_is,则将failing设置为true,如果我发现{{ 1}}。

提前谢谢!

1 个答案:

答案 0 :(得分:1)

您需要添加某种递归:

class StackOverflow
  def initialize(name)
    @name = name
  end

  def method_missing(argument, *args)
    argument = argument.to_s

    if argument =~ /failing/
      puts 'FOUND FAILING'
      puts argument
      puts args[0]
      return
    end

    if argument =~ /this_test_is/
      puts 'FOUND THIS TEST IS'
      puts argument
      puts args[0]
      return StackOverflow.new("this_test_is")
    end

    if argument =~ /this_works=/
      instance_variable_set("@#{argument.to_s.chop}", args[0])
      return
    else
      return instance_variable_get("@#{argument}").to_s
    end
  end
end

test = StackOverflow.new("post")
test.this_works = true
puts "IT WORKED: " + test.this_works
test.this_test_is.failing

打印此内容:

IT WORKED: true
FOUND THIS TEST IS
this_test_is

FOUND FAILING
failing