openstruct 上的 catch-all getter 方法?
catch-all getter method on openstruct?
如果我有一个 OpenStruct:
require 'ostruct'
open_struct = OpenStruct.new
我可以覆盖 []
这在某些情况下有效
open_struct.define_singleton_method(:[]) do |*args|
puts args.map(&:class)
puts args
end
open_struct.a = 1
open_struct[:a]
# => Symbol
# a
但是这个[]
方法在使用点法语法时不会被调用:
open_struct.a
# => 1
我正在尝试制作一个 class,它继承自 OpenStruct 并且更像一个 Javascript 对象(基本上我试图消除对 运行 call
在存储为值的 proc 上)
首先 - OpenStruct 的功能已经非常类似于 JavaScript(假定 #[]
是 #call
的同义词):
JS:
foo = {}
foo.bar = function() { console.log("Hello, world!"); };
foo.bar();
// => Hello, world!
Ruby:
foo = OpenStruct.new
foo.bar = proc { puts "Hello, world!" }
foo.bar[]
# => Hello, world!
如果你的意思是函数更像 Ruby...你可以覆盖 new_ostruct_member
:
require 'ostruct'
class AutoCallableOpenStruct < OpenStruct
protected def new_ostruct_member(name)
name = name.to_sym
unless respond_to?(name)
define_singleton_method(name) {
val = @table[name]
if Proc === val && val.arity == 0
val.call
else
val
end
}
define_singleton_method("#{name}=") { |x| modifiable[name] = x }
end
name
end
end
a = AutoCallableOpenStruct.new
a.name = "max"
a.helloworld = proc { puts "Hello, world!" }
a.hello = proc { |name| puts "Hello, #{name}!" }
a.name # non-Proc, retrieve
# => max
a.helloworld # nullary proc, autocall
# => Hello, world!
a.hello[a.name] # non-nullary Proc, retrieve (#[] invokes)
# => Hello, max!
请注意 Ruby 中的 OpenStruct
会减慢您的程序,如果可以避免则不应使用它。
如果我有一个 OpenStruct:
require 'ostruct'
open_struct = OpenStruct.new
我可以覆盖 []
这在某些情况下有效
open_struct.define_singleton_method(:[]) do |*args|
puts args.map(&:class)
puts args
end
open_struct.a = 1
open_struct[:a]
# => Symbol
# a
但是这个[]
方法在使用点法语法时不会被调用:
open_struct.a
# => 1
我正在尝试制作一个 class,它继承自 OpenStruct 并且更像一个 Javascript 对象(基本上我试图消除对 运行 call
在存储为值的 proc 上)
首先 - OpenStruct 的功能已经非常类似于 JavaScript(假定 #[]
是 #call
的同义词):
JS:
foo = {}
foo.bar = function() { console.log("Hello, world!"); };
foo.bar();
// => Hello, world!
Ruby:
foo = OpenStruct.new
foo.bar = proc { puts "Hello, world!" }
foo.bar[]
# => Hello, world!
如果你的意思是函数更像 Ruby...你可以覆盖 new_ostruct_member
:
require 'ostruct'
class AutoCallableOpenStruct < OpenStruct
protected def new_ostruct_member(name)
name = name.to_sym
unless respond_to?(name)
define_singleton_method(name) {
val = @table[name]
if Proc === val && val.arity == 0
val.call
else
val
end
}
define_singleton_method("#{name}=") { |x| modifiable[name] = x }
end
name
end
end
a = AutoCallableOpenStruct.new
a.name = "max"
a.helloworld = proc { puts "Hello, world!" }
a.hello = proc { |name| puts "Hello, #{name}!" }
a.name # non-Proc, retrieve
# => max
a.helloworld # nullary proc, autocall
# => Hello, world!
a.hello[a.name] # non-nullary Proc, retrieve (#[] invokes)
# => Hello, max!
请注意 Ruby 中的 OpenStruct
会减慢您的程序,如果可以避免则不应使用它。