gpt4 book ai didi

ruby - 这个 define_method 用例是不是太复杂了?

转载 作者:太空宇宙 更新时间:2023-11-03 18:25:18 24 4
gpt4 key购买 nike

三天来我一直在反对这个问题。我创建了一个模拟 html 页面的类,并告诉 cucumber 步骤定义在哪里填充表单数据:

class FlightSearchPage

def initialize(browser, page, brand)
@browser = browser
@start_url = page

#Get reference to config file
config_file = File.join(File.dirname(__FILE__), '..', 'config', 'site_config.yml')

#Store hash of config values in local variable
config = YAML.load_file config_file

@brand = brand #brand is specified by the customer in the features file

#Define instance variables from the hash keys
config.each do |k,v|
instance_variable_set("@#{k}",v)
end
end

def method_missing(sym, *args, &block)
@browser.send sym, *args, &block
end

def page_title
#Returns contents of <title> tag in current page.
@browser.title
end

def visit
@browser.goto(@start_url)
end

def set_origin(origin)
self.text_field(@route[:attribute] => @route[:origin]).set origin
end

def set_destination(destination)
self.text_field(@route[:attribute] => @route[:destination]).set destination
end

def set_departure_date(outbound)
self.text_field(@route[:attribute] => @date[:outgoing_date]).set outbound
end

# [...snip]

end

如您所见,我使用 instance_variable_set 创建了动态保存引用的变量,并且变量名称和值由配置文件提供(该文件旨在供非专业人士编辑)必须熟悉 Ruby)。

不幸的是,这是一个大而多毛的类,每次我想添加一个新字段时我都必须编辑源代码,这显然是糟糕的设计所以我一直在努力更进一步并创建使用 define_method 动态设置变量名称的方法,这是让我在过去几个晚上一直睡到凌晨 4 点的原因。

这是我所做的:

require File.expand_path(File.dirname(__FILE__) + '/flight_search_page')

class SetFieldsByType < FlightSearchPage
def text_field(config_hash)
define_method(config_hash) do |data|
self.text_field(config_hash[:attribute] => config_hash[:origin]).set data
end
end
end

想法是,添加新字段所需要做的就是向 YAML 文件添加新条目,define_method 将创建允许 Cucumber 填充它的方法。

目前,我在范围方面遇到了问题——Ruby 认为 define_method 是@browser 的成员。但我想知道的是:这是否可行?我完全误解了define_method吗?

最佳答案

Do you mean that you'd expect to see the requires and file loads outside the class definition?

不,在类定义中。 Ruby 类声明只是按照看到的顺序执行的代码。 attr_accessor 之类的东西只是碰巧对正在定义的类执行操作的类方法,在定义时。这看起来就像你想做的。

在您的情况下,您将改为读取 YAML 文件,并运行您自己的逻辑来创建访问器、构建所需的任何支持数据等。我并不完全理解用例,但这听起来并不异常或困难--还没有。

也就是说,将这些定义放在 YAML 文件中会带来多少“便利”?考虑一下我曾经做过的事情来创建我用来驱动 Watir 的页面实例:

class SomePage < HeavyWatir
has_text :fname # Assumed default CSS accessor pattern
has_text :whatever, accessor: 'some accessor mechanism', option: 'some other option'
end

has_xxx 是创建实例变量访问器的类方法(就像 attr_accessor 所做的那样),构建了一些其他的数据结构,我用来确保所有的东西都是应该在页面上实际上是,等等。例如,非常大致:

page = SomePage.new
page.visit
if page.missing_fields?
# Do something saying the page isn't complete
end

听起来好像你想要一些模糊相似的东西:你有一堆“东西”你想给类(或子类,或者你可以将它们混合成任意的类等)

那些“东西”具有额外的功能,该功能以多种方式工作,例如:

定义期间发生的事情

例如,has_text 将名称添加到页面元数据的类实例散列中,例如字段名称。

使用过程中发生的事情

例如,当 fname= 被调用时,在实例的元数据中设置一个标志,表明调用了 setter。

关于ruby - 这个 define_method 用例是不是太复杂了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12123804/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com