Interesting Ruby anomaly

H

Hal Fulton

Hello, all...

I ran across an interesting bit of behavior, and I'm not sure I
understand why it happens.

Here's the background. I have a SuperStruct class which I use frequently
(though I hope to find a better name for it). See the snippet on
rubyforge: http://rubyforge.org/snippet/detail.php?type=snippet&id=25

So. If you call SuperStruct.new, you get a class that is much like
a Struct; if you call SuperStruct.open instead, you get a class that
is more like an OpenStruct.

That is, in the latter case, if you reference a nonexistent attribute,
it will spring into existence:

klass = SuperStruct.open:)alpha) # Create with attr "alpha"
foo = klass.new
x = foo.beta # nil
foo.gamma = 5 # 5

In fact, when you referenced the getter OR the setter... then the getter
AND the setter would be defined. Make sense so far?

But this leads to an oddity...

foo.delta ||= 7 # gives an error!
foo.delta = foo.delta || 7 # I think this also gives an error

I had to fix this by saying: When the getter or setter is referenced,
define ONLY that method. I don't quite like this; but oh, well.

But puzzling out why it works this way has given me a headache.

What do you think?


Hal
 
J

James Britt

Hal said:
Hello, all...

I ran across an interesting bit of behavior, and I'm not sure I
understand why it happens.

Here's the background. I have a SuperStruct class which I use frequently
(though I hope to find a better name for it).

As far as naming goes, have you considered:

MegaStruct
UltraStruct
EvenBetterStruct
StructThatIsLikePlainOldStructButAlsoLikeOpenStruct


Hope this helps.




James


:)
 
C

Carl Youngblood

How bout UberStruct? (JK)

As far as naming goes, have you considered:

MegaStruct
UltraStruct
EvenBetterStruct
StructThatIsLikePlainOldStructButAlsoLikeOpenStruct

Hope this helps.

James

:)
 
H

Hal Fulton

James said:
As far as naming goes, have you considered:

MegaStruct
UltraStruct
EvenBetterStruct
StructThatIsLikePlainOldStructButAlsoLikeOpenStruct

Hope this helps.

Har har... yeah, I've also thought of

StarStruct
SelfdeStruct
StructOil
StructOut

:)

Hal
 
A

Anders K. Madsen

Har har... yeah, I've also thought of

StarStruct
SelfdeStruct
StructOil
StructOut

:)

ObStruct
ConStruct
DeStruct
DeconStruct
AbStruct
HasTrucked
MissTrucked

:p

--
Anders K. Madsen --- http://lillesvin.linux.dk

"There are 10 types of people in the world.
Those who understand binary - and those who don't."


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (GNU/Linux)

iD8DBQFBGwC0lNHJe/JASHcRAkmfAKCCa1N8PNVVtBFtC4hwlFoCS4vGtwCbBqTs
rCIZX/tiOJr/NjjOT7PCiRE=
=GNA5
-----END PGP SIGNATURE-----
 
N

nobu.nokada

Hi,

At Thu, 12 Aug 2004 12:49:50 +0900,
Hal Fulton wrote in [ruby-talk:108944]:
But this leads to an oddity...

foo.delta ||= 7 # gives an error!
foo.delta = foo.delta || 7 # I think this also gives an error

`len' is length of `args' to messod_missing at first, not
setter's. And I guess defined setter should fail if any
arguments given.


--- /tmp/nobu/superstruct-orig.rb 2004-08-12 15:19:33.000000000 +0900
+++ /tmp/nobu/superstruct.rb 2004-08-12 15:21:38.000000000 +0900
@@ -131,7 +131,7 @@ class SuperStruct
setsyms << setter
table << getter
- len = args.length
klass.class_eval do
define_method(setter) do |*args|
+ len = args.length
if len != 1
raise ArgumentError, "Wrong # of arguments (#{len} for 1)",
@@ -141,5 +141,5 @@ class SuperStruct
instance_variable_get(ivar)
end
- define_method(getter) do
+ define_method(getter) do ||
instance_variable_get(ivar)
end
@@ -148,10 +148,5 @@ class SuperStruct
self.send(setter,*args)
else
- if len == 0
- self.send(getter)
- else
- raise NoMethodError, "Undefined method '#{mname}' for #{self}",
- caller(1)
- end
+ self.send(getter,*args)
end
end
 
R

Robert Klemme

Hal Fulton said:
Hello, all...

I ran across an interesting bit of behavior, and I'm not sure I
understand why it happens.

Here's the background. I have a SuperStruct class which I use frequently
(though I hope to find a better name for it). See the snippet on
rubyforge: http://rubyforge.org/snippet/detail.php?type=snippet&id=25

So. If you call SuperStruct.new, you get a class that is much like
a Struct; if you call SuperStruct.open instead, you get a class that
is more like an OpenStruct.

That is, in the latter case, if you reference a nonexistent attribute,
it will spring into existence:

klass = SuperStruct.open:)alpha) # Create with attr "alpha"
foo = klass.new
x = foo.beta # nil
foo.gamma = 5 # 5

In fact, when you referenced the getter OR the setter... then the getter
AND the setter would be defined. Make sense so far?

But this leads to an oddity...

foo.delta ||= 7 # gives an error!
foo.delta = foo.delta || 7 # I think this also gives an error

I had to fix this by saying: When the getter or setter is referenced,
define ONLY that method. I don't quite like this; but oh, well.

But puzzling out why it works this way has given me a headache.

What do you think?

I think it doesn't happen with OpenStruct:

Personally I'd implement SuperStruct like this:

require 'ostruct'
class SuperStruct
def self.new(*attrs)
Struct.new( *attrs ).new
end

def self.open(*attrs)
st = OpenStruct.new
attrs.each {|at| st.send( "#{at}=", nil) }
st
end
end
=> <OpenStruct foo=nil>

But apparently you're adding more magic, so that's probably not a solution
for you.

Kind regards

robert
 
R

Robert Klemme

I think it doesn't happen with OpenStruct:


Personally I'd implement SuperStruct like this:

Forget that statement: I didn't see your comments, so your SuperStruct is
quite different from what my suggestion would yield.

Kind regards

robert
 
A

Anders K. Madsen

grep -i struct /usr/share/dict/words

That wouldn't give you anything with "truck" and "abstruct"/"abstract"
wouldn't turn up either...
beat this :)

Why would I? I never thought this was a competition...

I'm very impressed that you can use grep and the case-insensitive switch
to search in an ASCII-file, but I fail to see where the humour comes
in... Sorry. :-\

Madsen

--
Anders K. Madsen --- http://lillesvin.linux.dk

"There are 10 types of people in the world.
Those who understand binary - and those who don't."


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (GNU/Linux)

iD8DBQFBG0NxlNHJe/JASHcRAgG1AJ9gCJvh0Sek6HymLxtneAppRFHwvgCgguLy
NUuRrmhPUpVeaz3VfyQYCCc=
=8aPd
-----END PGP SIGNATURE-----
 
J

James Britt

Anders said:
That wouldn't give you anything with "truck" and "abstruct"/"abstract"
wouldn't turn up either...




Why would I? I never thought this was a competition...

I'm very impressed that you can use grep and the case-insensitive switch
to search in an ASCII-file, but I fail to see where the humour comes
in... Sorry. :-\


I'm pretty sure that "beat this" was a facetious, not serious, challenge.

But, as this branch of the thread careens into total foolishness, I
would award more game [0] points for names that manage to avoid any
direct reference to the literal string 'struct', yet still convey some
twisted spin on the original name.

James

[0] The game being, "Give Hal far more alternative names than he would
ever want to even remotely consider."

Maybe Ruby could use a Facetious module, so that one could write code
using :), :-O, and so on, and the interpreter would know to not *really*
execute the line. Just "sort of" execute it.

# But in the meantime ...

%w< :) :/ :} >.each { |grin| puts(grin) }
 
H

Hal Fulton

`len' is length of `args' to messod_missing at first, not
setter's. And I guess defined setter should fail if any
arguments given.

Of course! That is so clear now.

Thank you.

Hal
 
H

Hal Fulton

Robert said:
Personally I'd implement SuperStruct like this:
[snip]

But apparently you're adding more magic, so that's probably not a solution
for you.

Actually, it might. The code does need simplifying.
I sometimes do things the hard way.


Hal
 
H

Hal Fulton

James said:
Maybe Ruby could use a Facetious module, so that one could write code
using :), :-O, and so on, and the interpreter would know to not *really*
execute the line. Just "sort of" execute it.

That makes more sense than some of the RCRs I have seen.

Hal
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Interesting discussions 7
Interesting bug 3
What do you do when you need to attach data to an object instance? 16
An interesting blog 11
An interesting new RNG. 11
Using qt ruby 3
Interesting class 5
[ANN] SuperStruct 1

Members online

Forum statistics

Threads
474,155
Messages
2,570,871
Members
47,401
Latest member
CliffGrime

Latest Threads

Top