OpenStruct ã®å®Ÿè£…ã‚’ä½•ç‚¹ã‹æ”¹å–„ã—ãŸã„ã¨è€ƒãˆã¦ã„ã¾ã™ã€‚
-
[ruby-dev:40463]ã®ã‚ˆã†ãª respond_to? ã®æŒ™å‹•ã«ä¾å˜ã—ãŸéƒ¨åˆ†ã¯
æ›¸ãæ›ãˆãŸã„。protected メソッドã¨åŒåã®ãƒ¡ãƒ³ãƒãƒ¼ã¯å¾“æ¥é€šã‚Š
使用å¯èƒ½ã«ã€‚ -
new_ostruct_member ãªã©ã€ OpenStruct ã®å®Ÿè£…ã«ä½¿ã‚れã¦ã„ã‚‹
public メソッドã¨åŒåã®ãƒ¡ãƒ³ãƒãƒ¼ã‚’作ã‚ã†ã¨ã—ã¦ã‚‚ã€å€¤ã‚’å–り
出ãã†ã¨ã™ã‚Œã°äºˆæœŸã›ã¬ãƒ¡ã‚½ãƒƒãƒ‰ãŒå‘¼ã°ã‚Œã€ã¾ãŸä»®ã«ä»£å…¥ã§ãã¦
ã—ã¾ã†ã¨ã™ã‚Œã°èª¤å‹•作を招ãã®ã ã‹ã‚‰ã€ NameError を出ã™ã¹ã
ã§ã¯ãªã„ã ã‚ã†ã‹ã€‚ãŸã ã€ç„¡è¦–ã—ã¦ãã‚ŒãŸæ–¹ãŒä¸å®šãƒ‡ãƒ¼ã‚¿ã‚’å–り込む際ã«ã¯ä¾¿åˆ©ã‹ã‚‚
ã—れãªã„ã®ã§ã€æ˜Žç¤ºçš„ã«ãƒã‚§ãƒƒã‚¯ã®æœ‰ç„¡ã‚’指定ã•ã›ã‚‹æ–¹ãŒã‚ˆã„?
ãŸã¨ãˆã° OpenStruct.new(hash, validate = false) ã¨ãƒ•ラグを
åŠ ãˆã‚‹ãªã©ã€‚ -
class ã‚„ method ãªã©ã® Kernel モジュールメソッドã¨åŒåã®
メンãƒãƒ¼ã¯ã€ãƒ¦ãƒ¼ã‚¶ãŒæœ›ã‚€ãªã‚‰ä½¿ãˆã‚‹ã¹ãã§ã¯ãªã„ã‹ã€‚
 関心ã®ã‚ã‚‹æ–¹ã¯æ„見をãã ã•ã„。
 ã¨ã‚Šã‚ãˆãšä¸Šè¨˜ã®åŸºæœ¬éƒ¨åˆ†ã‚’ã²ã¨ã¾ã¨ã‚ã«ã—ãŸãƒ‘ッãƒã‚’付ã‘ã¾ã™ã€‚
–
Akinori MUSHA / http://akinori.org/
Index: lib/ostruct.rb
— lib/ostruct.rb (revision 26742)
+++ lib/ostruct.rb (working copy)
@@ -31,6 +31,11 @@
p data # → <OpenStruct country=“Australia”
population=20000000>
class OpenStruct
- METHOD_class = Kernel.instance_method(:class)
- METHOD_object_id = Kernel.instance_method(:object_id)
- METHOD_method = Kernel.instance_method(:method)
- METHOD_public_method = Kernel.instance_method(:public_method)
-
Create a new OpenStruct object. The optional +hash+, if given,
will
generate attributes and values. For example.
@@ -79,12 +84,25 @@ class OpenStruct
def new_ostruct_member(name)
name = name.to_sym
- unless self.respond_to?(name)
-
class << self; self; end.class_eval do
-
define_method(name) { @table[name] }
-
define_method("#{name}=") { |x| modifiable[name] = x }
- singleton = class << self; self; end
- if self.respond_to?(name)
-
protected_p = false
-
begin
-
owner = METHOD_public_method.bind(self).call(name).owner
-
rescue NameError
-
owner = METHOD_method.bind(self).call(name).owner
-
protected_p = true
-
end
-
if owner == singleton || protected_p
-
return name
-
elsif owner <= OpenStruct
-
raise NameError, "the name `#{name}' is reserved by
implementation (#{owner})"
end
end
- singleton.class_eval do
-
define_method(name) { @table[name] }
-
define_method("#{name}=") { |x| modifiable[name] = x }
- end
name
end
@@ -116,14 +134,14 @@ class OpenStruct
Returns a string containing a detailed summary of the keys and
values.
def inspect
- str = “#<#{self.class}”
-
str = “#<#{METHOD_class.bind(self).call}”
ids = (Thread.current[InspectKey] ||= [])
if ids.include?(object_id)
return str << ’ …>’
end
- ids << object_id
-
ids << METHOD_object_id.bind(self).call
begin
first = true
for k,v in @table
Index: test/ostruct/test_ostruct.rb
===================================================================
— test/ostruct/test_ostruct.rb (revision 26742)
+++ test/ostruct/test_ostruct.rb (working copy)
@@ -21,6 +21,47 @@ class TC_OpenStruct < Test::Unit::TestCa
assert_not_equal(o1, o2)
end -
def test_kernel_methods
-
o = OpenStruct.new
-
assert_nothing_raised(“The name ‘method’ should be available”) {
-
o.method = :something
-
assert_equal(:something, o.method)
-
}
-
o = OpenStruct.new
-
o.object_id = 123
-
o.class = “Foo”
-
assert_equal(“#<OpenStruct object_id=123, class="Foo">”,
o.inspect, -
"Setting 'class' should not affect the result of #inspect")
-
end
-
def test_protected_methods
-
o = OpenStruct.new
-
assert_nothing_raised(“The name ‘modifiable’ should be available”)
{ -
o.modifiable = :something
-
assert_equal(:something, o.modifiable)
-
}
-
assert_nothing_raised(“The name ‘table’ should be available”) {
-
o.table = :something
-
assert_equal(:something, o.table)
-
}
-
end
-
def test_reserved_methods
-
assert_raises(NameError) {
-
o = OpenStruct.new
-
o.inspect = "foo"
-
}
-
assert_raises(NameError) {
-
subclass = Class.new(OpenStruct)
-
o = subclass.new
-
o.inspect = "foo"
-
}
-
end
-
def test_inspect
foo = OpenStruct.new
assert_equal(“#”, foo.inspect)