Comments (8)
Yeah, Mash#[:key]=val returns the original value that was passed in as an argument, and not the converted value that was actually saved in the Mash.
It turns out that this comes down to a fundamental fact about the Ruby compiler (well, MRI, at least) - assignments always return the value passed in, regardless of what is returned in the body of the assignment method. We can confirm this like so:
class Foo
def bar=(val)
@bar = val * 2
return @bar
end
def bar
@bar
end
end
foo = Foo.new
foo.bar = 1 # => 1
foo.bar # => 2
As a sidenote, I found it really interesting to discover that #send behaves differently:
foo = Foo.new
foo.bar = 1 # => 1
foo.send :bar=, 1 # => 2
foo.bar # => 2
When compiling an assignment into bytecode, MRI actually adds some funky extra steps to ensure that the value passed in is returned instead of the return value of the method. But no such extra steps are added when compiling #send to bytecode, which is why #send has the same return behavior of any other normal method.
Point being, this is a matter of compiler behavior and not something that can be debugged here. 😓 😦 I recommend that this issue be closed.
from hashie.
Wow. OK, so much for "least surprise."
Fascinating. Thanks for doing the research.
I guess all that can be done is to close the issue... I'll put up a
question on StackOverflow just in case someone can think of a workaround.
I ended up not using Hashie anyway because I found it hard to get an
insensitive hash (I forget exactly why).
Chris
On Sun, Aug 11, 2013 at 4:05 PM, Danielle Sucher
[email protected]:
Yeah, Mash#[:key]=val returns the original value that was passed in as an
argument, and not the converted value that was actually saved in the Mash.It turns out that this comes down to a fundamental fact about the Ruby
compiler (well, MRI, at least) - assignments always return the value passed
in, regardless of what is returned in the body of the assignment method. We
can confirm this like so:class Foo
def bar=(val)
@bar = val * 2
return @bar
enddef bar
@bar
endend
foo = Foo.newfoo.bar = 1 # => 1foo.bar # => 2As a sidenote, I found it really interesting to discover that #send
behaves differently:foo = Foo.newfoo.bar = 1 # => 1foo.send :bar=, 1 # => 2foo.bar # => 2
When compiling an assignment into bytecode, MRI actually adds some funky
extra steps to ensure that the value passed in is returned instead of the
return value of the method. But no such extra steps are added when
compiling #send to bytecode, which is why #send has the same return
behavior of any other normal method.Point being, this is a matter of compiler behavior and not something that
can be debugged here. [image: 😓][image: 😦] I recommend
that this issue be closed.—
Reply to this email directly or view it on GitHubhttps://github.com//issues/108#issuecomment-22467355
.
Chris Phoenix
[email protected]
650-776-5195
from hashie.
OK, I put up the question hat-tipping Danielle for the research.
I did think of one thing to do while writing the question: (c.foo ||
c.send(:foo=, [])) << 5 will work, even though (c.foo ||= []) << 5 will
not; It might (or might not) be worth documenting that.
Chris
On Sun, Aug 11, 2013 at 6:22 PM, Chris Phoenix [email protected] wrote:
Wow. OK, so much for "least surprise."
Fascinating. Thanks for doing the research.
I guess all that can be done is to close the issue... I'll put up a
question on StackOverflow just in case someone can think of a workaround.I ended up not using Hashie anyway because I found it hard to get an
insensitive hash (I forget exactly why).Chris
On Sun, Aug 11, 2013 at 4:05 PM, Danielle Sucher <[email protected]
wrote:
Yeah, Mash#[:key]=val returns the original value that was passed in as an
argument, and not the converted value that was actually saved in the Mash.It turns out that this comes down to a fundamental fact about the Ruby
compiler (well, MRI, at least) - assignments always return the value passed
in, regardless of what is returned in the body of the assignment method. We
can confirm this like so:class Foo
def bar=(val)
@bar = val * 2
return @bar
enddef bar
@bar
endend
foo = Foo.newfoo.bar = 1 # => 1foo.bar # => 2As a sidenote, I found it really interesting to discover that #send
behaves differently:foo = Foo.newfoo.bar = 1 # => 1foo.send :bar=, 1 # => 2foo.bar # => 2
When compiling an assignment into bytecode, MRI actually adds some funky
extra steps to ensure that the value passed in is returned instead of the
return value of the method. But no such extra steps are added when
compiling #send to bytecode, which is why #send has the same return
behavior of any other normal method.Point being, this is a matter of compiler behavior and not something that
can be debugged here. [image: 😓][image: 😦] I recommend
that this issue be closed.—
Reply to this email directly or view it on GitHubhttps://github.com//issues/108#issuecomment-22467355
.Chris Phoenix
[email protected]
650-776-5195
Chris Phoenix
[email protected]
650-776-5195
from hashie.
Please, stop using mi name to document your code, thanks! :)
from hashie.
@bar 😇 💓 💖 💞
from hashie.
HAHAHAH
from hashie.
yep, we all love to foo bar :')
from hashie.
I am closing this. Please open a new issue if you think it's still a problem. This was an interesting discussion, too, btw!
from hashie.
Related Issues (20)
- Problem flattening multiple nested properties via Trash HOT 3
- Release v. next HOT 2
- Integer key upsets Hashie::Mash with SymbolizeKeys extension HOT 16
- Slice doesn't work using symbols HOT 5
- I got in dev a failing test from master, how to properly setup? HOT 5
- RFC: Switch to Github Actions for CI HOT 3
- Multiple Trash properties that use the same key from a source hash HOT 3
- Undefined quiet method HOT 4
- New Release? HOT 3
- Behavior change in accessing Mash values in 5.0 release HOT 5
- [Informative] `deep_symbolize_keys` broken in Rails 7 with `Mash` HOT 7
- [Question] Why use :to_sym in Hashie::Mash#convert_key HOT 1
- Release version 5 HOT 1
- Memory leak possible HOT 5
- DeepMerge changes ActiveRecord instance HOT 2
- Trash warning when translating string to symbol
- Mash.load is insecure HOT 5
- Including MethodAccessWithOverride in Hashie::Mash breaks dup method
- PredefinedValues is undefined ... :( HOT 1
- Can't call to_hash with nested `Sequel::Postgres::JSONBHash` HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from hashie.