shorthand

Discussion in 'Ruby' started by Roger Pack, Jun 14, 2010.

  1. Roger Pack

    Roger Pack Guest

    I read this once:

    Operator ||= can be shorthand for code like:
    x = "(some fallback value)" unless respond_to? :x or x

    How would that look like exactly, in shorthand, any guesses?
    -r
    --
    Posted via http://www.ruby-forum.com/.
     
    Roger Pack, Jun 14, 2010
    #1
    1. Advertising

  2. On Mon, Jun 14, 2010 at 5:48 PM, Roger Pack <> wrote=
    :
    > I read this once:
    >
    > Operator ||=3D can be shorthand for code like:
    > =A0x =3D "(some fallback value)" unless respond_to? :x or x
    >
    > How would that look like exactly, in shorthand, any guesses?



    I don't know where you read that, but it has no basis in reality. The
    semantics of ||=3D have nothing to do with whether or not a method
    exists.

    The closest translation of

    x ||=3D y

    (x || x =3D y)

    This is close, except that it will blow up if x isn't already defined.

    another alternative might be

    (defined? x) ? (x || x =3D y) : y

    Which avoids the problem when x isn't defined, but isn't exactly what
    the 'compiled' ruby code does, whether that 'code' is YARV 'byte
    codes' or an AST in MRI pre 1.9

    --=20
    Rick DeNatale

    Blog: http://talklikeaduck.denhaven2.com/
    Github: http://github.com/rubyredrick
    Twitter: @RickDeNatale
    WWR: http://www.workingwithrails.com/person/9021-rick-denatale
    LinkedIn: http://www.linkedin.com/in/rickdenatale
     
    Rick DeNatale, Jun 14, 2010
    #2
    1. Advertising

  3. Roger Pack <> writes:

    > I read this once:
    >
    > Operator ||= can be shorthand for code like:
    > x = "(some fallback value)" unless respond_to? :x or x
    >
    > How would that look like exactly, in shorthand, any guesses?
    > -r


    Sure you don't mean ||= as a way of easily implementing basic
    memoization?

    Example:

    class Foo
    def bar
    @bar ||= begin
    # do some calculations here
    1 + rand
    end
    end
    end

    f = Foo.new
    f.bar # => 1.01853966346202
    f.bar # => 1.01853966346202
     
    Dominik Honnef, Jun 15, 2010
    #3
  4. On 6/14/10, Rein Henrichs <> wrote:
    > On 2010-06-14 14:48:36 -0700, Roger Pack said:
    >
    >> I read this once:
    >>
    >> Operator ||= can be shorthand for code like:
    >> x = "(some fallback value)" unless respond_to? :x or x
    >>
    >> How would that look like exactly, in shorthand, any guesses?
    >> -r

    >
    > The expression:
    >
    > a ||= b
    >
    > is equivalent to:
    >
    > a || a = b
    >
    > in most cases. To be pedantic, it is actually:
    >
    > (defined?(a) && a) || a = b


    Except if there's a method named a, defined?(a) returns "method", so
    this still isn't exactly equivalent. Ruby is tricksy.
     
    Caleb Clausen, Jun 15, 2010
    #4
  5. Roger Pack

    Josh Cheek Guest

    [Note: parts of this message were removed to make it a legal post.]

    On Mon, Jun 14, 2010 at 5:41 PM, Rick DeNatale <>wrote:

    > This is close, except that it will blow up if x isn't already defined.
    >
    > another alternative might be
    >
    > (defined? x) ? (x || x = y) : y
    >
    > Which avoids the problem when x isn't defined, but isn't exactly what
    > the 'compiled' ruby code does, whether that 'code' is YARV 'byte
    > codes' or an AST in MRI pre 1.9
    >
    >

    This implies to me that if x is not defined, then return y without modifying
    x. But this contradicts the reason I used ||= for (lazy assignment).

    $ irb


    ruby-1.9.1-p378 > defined? x
    => nil


    ruby-1.9.1-p378 > defined? x
    => nil


    ruby-1.9.1-p378 > x ||= 5
    => 5


    ruby-1.9.1-p378 > x
    => 5
     
    Josh Cheek, Jun 15, 2010
    #5
  6. On Mon, Jun 14, 2010 at 8:35 PM, Josh Cheek <> wrote:
    > On Mon, Jun 14, 2010 at 5:41 PM, Rick DeNatale <>wrote:
    >
    >> This is close, except that it will blow up if x isn't already defined.
    >>
    >> another alternative might be
    >>
    >> (defined? x) ? (x || x = y) : y
    >>
    >> Which avoids the problem when x isn't defined, but isn't exactly what
    >> the 'compiled' ruby code does, whether that 'code' is YARV 'byte
    >> codes' or an AST in MRI pre 1.9
    >>
    >>

    > This implies to me that if x is not defined, then return y without modifying
    > x. But this contradicts the reason I used ||= for (lazy assignment).
    >


    Yeah it was a typo on my part

    (defined? x) ? (x || x = y) : (x = y)

    As I said before though, all of these are approximations. The
    defined? guard is just to avoid the undefined variable error.

    For

    x ||= y

    The compiler defines x when it sees it, normally a local variable only
    gets defined when it actually gets a value assigned.

    --
    Rick DeNatale

    Blog: http://talklikeaduck.denhaven2.com/
    Github: http://github.com/rubyredrick
    Twitter: @RickDeNatale
    WWR: http://www.workingwithrails.com/person/9021-rick-denatale
    LinkedIn: http://www.linkedin.com/in/rickdenatale
     
    Rick DeNatale, Jun 15, 2010
    #6
  7. Roger Pack wrote:
    > I read this once:
    >
    > Operator ||= can be shorthand for code like:
    > x = "(some fallback value)" unless respond_to? :x or x
    >
    > How would that look like exactly, in shorthand, any guesses?


    foo ||= 5

    is shorthand for

    foo = foo || 5

    which means
    (a) 'foo' is a local variable (because it's an assignment)
    (b) it will be set to 5 if it is currently nil or false, otherwise it
    will retain its previous value.

    The thing you read about respond_to? is wrong. This construct is nothing
    to do with a method called foo, as you can easily demonstrate:

    $ irb --simple-prompt
    >> def foo
    >> 9
    >> end

    => nil
    >> respond_to? :foo

    => true
    >> foo ||= 5

    => 5
    >> foo

    => 5
    --
    Posted via http://www.ruby-forum.com/.
     
    Brian Candler, Jun 15, 2010
    #7
  8. On Tue, Jun 15, 2010 at 1:24 PM, Brian Candler <> wrote:
    > foo ||= 5
    >
    > is shorthand for
    >
    > foo = foo || 5


    NO it is NOT, although many Rubyist seem to cling to this idea.

    see http://talklikeaduck.denhaven2.com/2008/04/26/x-y-redux

    and recent discussion on this very thread.

    The difference between

    x ||= 5

    and

    x = x | | 5

    is that if x has a truthy value, then NO assignment will be done in
    the first case (including assignment through a 'setter' method) in the
    first case, but it will in the second.


    --
    Rick DeNatale

    Blog: http://talklikeaduck.denhaven2.com/
    Github: http://github.com/rubyredrick
    Twitter: @RickDeNatale
    WWR: http://www.workingwithrails.com/person/9021-rick-denatale
    LinkedIn: http://www.linkedin.com/in/rickdenatale
     
    Rick DeNatale, Jun 15, 2010
    #8
  9. Rick Denatale wrote:
    > The difference between
    >
    > x ||= 5
    >
    > and
    >
    > x = x | | 5
    >
    > is that if x has a truthy value, then NO assignment will be done in
    > the first case (including assignment through a 'setter' method) in the
    > first case, but it will in the second.


    I never said that foo.x ||= 5 behaves like this. This *is* a method call
    :)x=) not a local variable assignment.

    class Foo
    def initialize(x=nil)
    self.x = x
    end
    def x
    @x
    end
    def x=(x)
    puts "set to #{x}"
    @x = x
    end
    end
    f = Foo.new
    f.x ||= 3
    f.x ||= 5
    --
    Posted via http://www.ruby-forum.com/.
     
    Brian Candler, Jun 17, 2010
    #9
  10. On Thu, Jun 17, 2010 at 11:07 AM, Brian Candler <> wrote:
    > I never said that foo.x ||= 5 behaves like this. This *is* a method call
    > :)x=) not a local variable assignment.


    No, but you said that "foo ||= 5 is shorthand for foo = foo || 5"
    which implies the same semantics, but...

    class Foo
    def initialize(x=nil)
    self.x = x
    end
    def x
    @x
    end
    def x=(x)
    puts "set to #{x}"
    @x = x
    end
    end
    f = Foo.new
    f.x ||= 3
    f.x ||= 5

    f.x = f.x || 6

    produces:

    set to
    set to 3
    set to 3


    See the difference?

    --
    Rick DeNatale

    Blog: http://talklikeaduck.denhaven2.com/
    Github: http://github.com/rubyredrick
    Twitter: @RickDeNatale
    WWR: http://www.workingwithrails.com/person/9021-rick-denatale
    LinkedIn: http://www.linkedin.com/in/rickdenatale
     
    Rick DeNatale, Jun 17, 2010
    #10
  11. 2010/6/14 Roger Pack <>:
    > I read this once:
    >
    > Operator ||=3D can be shorthand for code like:
    > =A0x =3D "(some fallback value)" unless respond_to? :x or x
    >
    > How would that look like exactly, in shorthand, any guesses?


    You can do this:

    x ||=3D (x() rescue "(some fallback value)")

    I did not think about this long enough to look at all the effects with
    local variables shadowing methods but it's something you can play
    with. :)

    Kind regards

    robert

    --=20
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
     
    Robert Klemme, Jun 18, 2010
    #11
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. foreach shorthand

    , Mar 25, 2005, in forum: C++
    Replies:
    2
    Views:
    646
    =?iso-8859-1?Q?Ali_=C7ehreli?=
    Mar 25, 2005
  2. David W
    Replies:
    0
    Views:
    991
    David W
    Jan 17, 2007
  3. Foxpointe

    Shorthand for namespaces

    Foxpointe, Oct 31, 2006, in forum: XML
    Replies:
    4
    Views:
    455
    Foxpointe
    Oct 31, 2006
  4. Replies:
    7
    Views:
    426
  5. Tilman  Kispersky
    Replies:
    2
    Views:
    392
    Paul Hankin
    Jun 8, 2008
Loading...

Share This Page