# Improving handling of reserved names in OpenStruct

**URL:** <https://www.ruby-forum.com/t/improving-handling-of-reserved-names-in-openstruct/184000>\
**Category:** Development\
**Created:** [February 23, 2010, 7:17pm UTC](https://www.ruby-forum.com/t/improving-handling-of-reserved-names-in-openstruct/184000 "2010-02-23T19:17:05Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Akinori\_MUSHA](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/b782af/32.png) [@Akinori\_MUSHA](https://www.ruby-forum.com/u/Akinori_MUSHA)\
**Post date:** [February 23, 2010, 7:17pm UTC](https://www.ruby-forum.com/t/improving-handling-of-reserved-names-in-openstruct/184000/1 "2010-02-23T19:17:05Z")

</div>

ã€€OpenStruct ã®å®Ÿè£…ã‚’ä½•ç‚¹ã‹æ”¹å–„ã—ãŸã„ã¨è€ƒãˆã¦ã„ã¾ã™ã€‚

1. [ruby-dev:40463]ã®ã‚ˆã†ãª respond\_to? ã®æŒ™å‹•ã«ä¾å­˜ã—ãŸéƒ¨åˆ†ã¯  
æ›¸ãæ›ãˆãŸã„ã€‚protected ãƒ¡ã‚½ãƒƒãƒ‰ã¨åŒåã®ãƒ¡ãƒ³ãƒãƒ¼ã¯å¾“æ¥é€šã‚Š  
ä½¿ç”¨å¯èƒ½ã«ã€‚

2. new\_ostruct\_member ãªã©ã€ OpenStruct ã®å®Ÿè£…ã«ä½¿ã‚ã‚Œã¦ã„ã‚‹  
public ãƒ¡ã‚½ãƒƒãƒ‰ã¨åŒåã®ãƒ¡ãƒ³ãƒãƒ¼ã‚’ä½œã‚ã†ã¨ã—ã¦ã‚‚ã€å€¤ã‚’å–ã‚Š  
å‡ºãã†ã¨ã™ã‚Œã°äºˆæœŸã›ã¬ãƒ¡ã‚½ãƒƒãƒ‰ãŒå‘¼ã°ã‚Œã€ã¾ãŸä»®ã«ä»£å…¥ã§ãã¦  
ã—ã¾ã†ã¨ã™ã‚Œã°èª¤å‹•ä½œã‚’æ‹›ãã®ã ã‹ã‚‰ã€ NameError ã‚’å‡ºã™ã¹ã  
ã§ã¯ãªã„ã ã‚ã†ã‹ã€‚

3. class ã‚„ method ãªã©ã® Kernel ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ãƒ¡ã‚½ãƒƒãƒ‰ã¨åŒåã®  
ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€ãƒ¦ãƒ¼ã‚¶ãŒæœ›ã‚€ãªã‚‰ä½¿ãˆã‚‹ã¹ãã§ã¯ãªã„ã‹ã€‚

ã€€é–¢å¿ƒã®ã‚ã‚‹æ–¹ã¯æ„è¦‹ã‚’ãã ã•ã„ã€‚

ã€€ã¨ã‚Šã‚ãˆãšä¸Šè¨˜ã®åŸºæœ¬éƒ¨åˆ†ã‚’ã²ã¨ã¾ã¨ã‚ã«ã—ãŸãƒ‘ãƒƒãƒã‚’ä»˜ã‘ã¾ã™ã€‚

–  
Akinori MUSHA / [http://akinori.org/](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 \<\< 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)
