我想实现我自己的类加载调用方法。
我的第一个例子来自PaperClip
,其中行has_attached_file
直接写在类上,并引用另一个植入(lib / Paperclip)。
我想实现一个在类上调用其他方法的方法。我希望它看起来链接before_filter
,但在模型上。
这个想法是不必手动调用您想要的每个方法的特定方法。模型开头只需要一行即可。
我尝试使用Concern
但据我所知,我只能定义类/实例方法,包含一些依赖项等等。
我想针对2种方法watch_here
和go_for_it
调用方法do_it_again
。我不想这样称呼它:
def go_for_it
watch_here :go_for_it
puts "Do it!"
end
def do_it_again
watch_here :do_it_again
puts "Do it again!"
end
private
def watch_here(name)
puts "I'm watching on #{name}"
end
我宁愿有类似的东西:
watch_here :go_for_it, :do_it_again
谢谢你的帮助!
答案 0 :(得分:3)
所以我自己测试了这个&&进一步回到@max
的答案(无论如何我都有点想,但他肯定正确指出了......)
您可以使用许多资源:
has_attached_file
friendly_id
经过一些简短的研究,我发现了这个问题: Ruby on Rails - passing a returned value of a method to has_attached_file. Do I get Ruby syntax wrong?
问题是您尝试在声明中使用实例方法
picture_sizes_as_strings
(has_attached_image
)
您正在寻找的是与宣布课程有关。我有这么多的经验,所以我写这个是为了我自己的利益:
对于那些来自静态面向对象语言的人,比如C ++和Java,开放类的概念是非常陌生的。 Ruby有开放课程意味着什么?这意味着在运行时可以更改类的定义 。 Ruby中的所有类都是开放的,用户可以随时更改。
class Talker
def self.say(*args)
puts "Inside self.say"
puts "self = #{self}"
args.each do |arg|
method_name = ("say_" + arg.to_s).to_sym
send :define_method, method_name do
puts arg
end
end
end
end
class MyTalker < Talker
say :hello
end
m = MyTalker.new
m.say_hello
似乎如果你 delcare 这个类,它将在init运行声明(?)方法。这些方法可用于填充对象的其他部分...在has_many :associations
的情况下,它将创建@parent.associations
的实例方法。
由于ActiveRecord::Concerns
是模块,因此您需要对其进行处理(根据我找到的epic tutorial):
#app/models/concerns.rb
require 'active_support/concern'
module Helper
extend ActiveSupport::Concern
module ClassMethods
def help(*args) #-> each argument represents a method
args.each do |arg|
method_name = ("say_" + arg.to_s).to_sym
send :define_method, method_name do
puts arg
end
end
end
end
end
#app/models/x.rb
class X < ActiveRecord::Base
include Helper
help :help
end
@x = X.new
@x.say_help #-> puts "help"
[[仍在解决其余问题]] - 如何添加实例方法;似乎super
效果不佳
答案 1 :(得分:2)
instance_eval
和class_eval
。
请注意,这是一个非常高级的主题,您应该对Ruby中的类,模块和消息传递如何工作有一个公平的理解!
module Magic
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def make_awesome
# self here is the class - so we are adding class methods
self.instance_eval do
def magic_class_method
puts "I'm a metamagical class method, deal with it."
end
# you could call another class method such as
# before_save :magic_instance_method
end
self.class_eval do
def magic_instance_method
puts "I'm metamagical instance method, deal with it."
end
end
end
end
end
class Test
include Magic
make_awesome
end
Test.magic_class_method
# => "I'm a metamagical class method, deal with it."
Test.magic_instance_method
# => "I'm metamagical instance method, deal with"
这有点违反直觉,但这种疯狂背后有一个原因:
在instance_eval
中,接收者本身就是Test类。请记住,类名只是一个指向类Class
的实例的常量。
class_eval
是Module类的一种方法,意味着接收器将是一个模块或一个类。传递给class_eval的块在该类的上下文中进行计算,就像使用class
关键字声明类一样。
补充阅读: