我希望在控制器中使用一种方法:
class Hash
def sort_by_array a; Hash[sort_by{|k, _| a.index(k) || length}] end
end
但是将代码放入控制器后,我收到错误消息:class definition in method body
我尝试删除了class Hash
和第二个end
,也尝试了
class Hash
def self.class.sort_by_array a; Hash[sort_by{|k, _| a.index(k) || length}] end
end
但是我仍然无法停止错误
作为参考,以下是控制器:
class StaticPagesController < ApplicationController
def main
class Hash
def self.class.sort_by_array a; Hash[sort_by{|k, _| a.index(k) || length}] end
end
@languages = Listing.group_by(&:language)
@languages.sort_by_array(@languages)
end
end
答案 0 :(得分:2)
当您在另一个类的方法内定义一个类时,就会发生该错误。即您可能正在执行以下操作:
class SomeClass
def some_method
class Hash
def sort_by_array(a)
end
end
end
end
假设您想通过添加方法Hash
来扩展sort_by_array
对象的功能,则可以像下面这样进行猴子修补:
lib / extensions / hash.rb
module Extensions
module Hash
def sort_by_array(a)
sort_by do |k, _|
a.index(k) || length
end
end
end
end
即假设您要扩展功能的另一个类:
lib / extensions / active_record / base.rb
module Extensions
module ActiveRecord
module Base
def say_hello_world
puts 'Hello World!'
end
end
end
end
config / initializers / extensions.rb
Hash.include Extensions::Hash
ActiveRecord::Base.include Extensions::ActiveRecord::Base
# rails console
some_array = [:a, :c, :b]
some_hash = { a: 1, b: 2, c: 3 }
some_hash.sort_by_array(some_array)
# => [[:a, 1], [:c, 3], [:b, 2]]
user = User.find(1)
user.say_hello_world
# => 'Hello World!'
lib / extensions / hash.rb
module Extensions
module Hash
def self.included(base)
base.extend ClassMethods
base.include InstanceMethods
end
# define your Hash "class methods" here inside ClassMethods
module ClassMethods
# commented out because not yet fully working (check update later)
# # feel free to remove this part (see P.S. for details)
# def self.extended(base)
# instance_methods.each do |method_name|
# raise NameError, "#{method_name} method already defined!" if (base.singleton_methods - instance_methods).include? method_name
# end
# end
end
# define your Hash "instance methods" here inside InstanceMethods
module InstanceMethods
# commented out because not yet fully working (check update later)
# # feel free to remove this part (see P.S. for details)
# def self.included(base)
# instance_methods.each do |method_name|
# raise NameError, "#{method_name} method already defined!" if (base.instance_methods - instance_methods).include? method_name
# end
# end
def sort_by_array(a)
sort_by do |k, _|
a.index(k) || length
end
end
end
end
end
即假设您要扩展功能的另一个类:
lib / extensions / active_record / base.rb
module Extensions
module ActiveRecord
module Base
def self.included(base)
base.extend ClassMethods
base.include InstanceMethods
end
module ClassMethods
# commented out because not yet fully working (check update later)
# # feel free to remove this part (see P.S. for details)
# def self.extended(base)
# instance_methods.each do |method_name|
# raise NameError, "#{method_name} method already defined!" if (base.singleton_methods - instance_methods).include? method_name
# end
# end
def say_hello_mars
puts 'Hello Mars!'
end
end
module InstanceMethods
# commented out because not yet fully working (check update later)
# # feel free to remove this part (see P.S. for details)
# def self.included(base)
# instance_methods.each do |method_name|
# raise NameError, "#{method_name} method already defined!" if (base.instance_methods - instance_methods).include? method_name
# end
# end
def say_hello_world
puts 'Hello World!'
end
end
end
end
end
config / initializers / extensions.rb
Hash.include Extensions::Hash
ActiveRecord::Base.include Extensions::ActiveRecord::Base
# rails console
some_array = [:a, :c, :b]
some_hash = { a: 1, b: 2, c: 3 }
some_hash.sort_by_array(some_array)
# => [[:a, 1], [:c, 3], [:b, 2]]
user = User.find(1)
user.say_hello_world
# => 'Hello World!'
ActiveRecord::Base.say_hello_mars
# => 'Hello Mars!'
PS,可以说,如果已经定义了一种方法,则无需引发错误,但这只是我个人的喜好,可以防止出现“ bug”(例如,如果您还定义了一些“ gems”完全相同的方法名称,但功能不同,您无法控制)。随时删除它们。
答案 1 :(得分:1)
将其放在单独的文件中。这将扩展基类config/initializers/hash.rb
,并允许您在整个应用程序中使用。
最简单的方法是将代码放入https://github.com/rails/rails/tree/master/activesupport/lib/active_support/core_ext
中,然后重新启动服务器。
或者更好,类似于Rails的操作方式(例如lib/core_ext/hash/sort_by_array.rb
):
将您的代码放在这里:require "core_ext/hash/sort_by_array"
然后添加此路径以自动加载,或从您要使用它的位置手动要求它,如下所示:
{{1}}。