GithubHelp home page GithubHelp logo

Comments (8)

DanielleSucher avatar DanielleSucher commented on July 20, 2024

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.

ChrisJPhoenix avatar ChrisJPhoenix commented on July 20, 2024

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
end

def bar
@bar
endend
foo = Foo.newfoo.bar = 1 # => 1foo.bar # => 2

As 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.

ChrisJPhoenix avatar ChrisJPhoenix commented on July 20, 2024

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
end

def bar
@bar
endend
foo = Foo.newfoo.bar = 1 # => 1foo.bar # => 2

As 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.

bar avatar bar commented on July 20, 2024

Please, stop using mi name to document your code, thanks! :)

from hashie.

DanielleSucher avatar DanielleSucher commented on July 20, 2024

@bar 😇 💓 💖 💞

from hashie.

j2labs avatar j2labs commented on July 20, 2024

HAHAHAH

from hashie.

bar avatar bar commented on July 20, 2024

yep, we all love to foo bar :')

from hashie.

dblock avatar dblock commented on July 20, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.