Adım adım tanımlarının bir Salatalık adımı tanım dosyasında tanımlanmasına benzer şekilde veya bir Sinatra uygulamasında yollar tanımlanmasına benzer şekilde Ruby projem için bir tür "sınıfsız DSL" yaratmanın nasıl çalıştığını anlamaya çalışıyorum. Bunun olan yöntemlerin bir grup ile küresel (Kernel
) ad kirletme için kötü bir uygulamadır varsayıyorumRuby'de sınıfsız bir DSL nasıl oluşturulur?
#sample.rb
when_string_matches /hello (.+)/ do |name|
call_another_method(name)
end
:
Örneğin, ben bütün DSL fonksiyonları çağrılan bir dosyayı sahip olmak istiyorum projeme özel. Dolayısıyla, kitaplığımda when_string_matches
ve call_another_method
yöntemleri tanımlanacak ve sample.rb
dosyası bir şekilde DSL yöntemlerimin bağlamında değerlendirilecektir.
Güncelleme: İşte bu DSL yöntemleri halen tanımlanmaktadır nasıl bir örnek:
yöntemleri sınıflandırma olan bir sınıfında tanımlanmıştır DSL (ı arasındaki bu yöntemleri yeniden bir yolunu bulmak istiyorum basit DSL ve sınıf örneklerini): programımın başlatma sırasında bir noktada sonra
module MyMod
class Action
def call_another_method(value)
puts value
end
def handle(text)
# a subclass would be expected to define
# this method (as an alternative to the
# simple DSL approach)
end
end
end
, ben sample.rb
dosyayı ayrıştırmak ve bu eylemleri depolamak istediğiniz sonradan yürütülecek:
module MyMod
class Parser
# parse the file, saving the blocks and regular expressions to call later
def parse_it
file_contents = File.read('sample.rb')
instance_eval file_contents
end
# doesnt seem like this belongs here, but it won't work if it's not
def self.when_string_matches(regex, &block)
MyMod.blocks_for_executing_later << { regex: regex, block: block }
end
end
end
# Later...
module MyMod
class Runner
def run
string = 'hello Andrew'
MyMod.blocks_for_executing_later.each do |action|
if string =~ action[:regex]
args = action[:regex].match(string).captures
action[:block].call(args)
end
end
end
end
end
Şu ana kadar sahip olduğum sorun (ve yukarıda bahsetmediğim çeşitli şeyler), dosyada bir blok tanımlandığında, örnek yöntemi kullanılamıyor. Şu anda farklı bir sınıfta). Ama benim yapmak istediğim, Parser
sınıfında değerlendirmekten ziyade bir örnek oluşturma ve bu bağlamda değerlendirme yapma gibi. Ama bunu nasıl yapacağımı bilmiyorum.
Umarım bu mantıklıdır. Herhangi bir yardım, deneyim veya tavsiye takdir edilecektir.
def when_string_matches(regex)
# do whatever is required to produce `my_string` and `name`
yield(name) if my_string =~ regex
end
:
Orada sindirmek için bir çok şey var, çünkü bazısı biraz başımdan geçti, ama yine de yararlı. Teşekkürler! – Andrew