Lame question about instance variable and attribute

D

dkmd_nielsen

Assuming an attribute :field is defined, is there a processing
difference between using @field and self.field [within the defining
class?] Does the ruby interpretter take a different path in yielding
the value depending how it is referenced? I haven't notice anything.
I'm just curious if the interpretter takes extra steps when yielding
self.field.

Thanks
 
J

Jesús Gabriel y Galán

Assuming an attribute :field is defined, is there a processing
difference between using @field and self.field [within the defining
class?] Does the ruby interpretter take a different path in yielding
the value depending how it is referenced? I haven't notice anything.
I'm just curious if the interpretter takes extra steps when yielding
self.field.

@field accessed the instance variable directly, while self.field calls
the method "field" on self. So the paths are completely different:


irb(main):001:0> require 'parse_tree'
=> true
irb(main):027:0> class B
irb(main):028:1> attr_reader :b
irb(main):029:1> def test
irb(main):030:2> @b
irb(main):031:2> end
irb(main):035:1> def test3
irb(main):036:2> self.b
irb(main):037:2> end
irb(main):038:1> end
=> nil
irb(main):039:0> ParseTree.new.parse_tree_for_method(B, :test)
=> [:defn, :test, [:scope, [:block, [:args], [:ivar, :mad:b]]]]
irb(main):040:0> ParseTree.new.parse_tree_for_method(B, :test3)
=> [:defn, :test3, [:scope, [:block, [:args], [:call, [:self], :b]]]]

Jesus.
 
D

dkmd_nielsen

Assuming an attribute :field is defined, is there a processing
difference between using @field and self.field [within the defining
class?]  Does the ruby interpretter take a different path in yielding
the value depending how it is referenced?  I haven't notice anything.
I'm just curious if the interpretter takes extra steps when yielding
self.field.

@field accessed the instance variable directly, while self.field calls
the method "field" on self. So the paths are completely different:

irb(main):001:0> require 'parse_tree'
=> true
irb(main):027:0> class B
irb(main):028:1> attr_reader :b
irb(main):029:1> def test
irb(main):030:2> @b
irb(main):031:2> end
irb(main):035:1> def test3
irb(main):036:2> self.b
irb(main):037:2> end
irb(main):038:1> end
=> nil
irb(main):039:0> ParseTree.new.parse_tree_for_method(B, :test)
=> [:defn, :test, [:scope, [:block, [:args], [:ivar, :mad:b]]]]
irb(main):040:0> ParseTree.new.parse_tree_for_method(B, :test3)
=> [:defn, :test3, [:scope, [:block, [:args], [:call, [:self], :b]]]]

Jesus.

So, in processing that involves many iterations, one should most
definitely use the instance variable reference. Correct?

When would it be proper to use the self. reference?

Thanks, again.
 
T

Thomas B.

dkmd_nielsen said:
When would it be proper to use the self. reference?

I think never. The exception is when the setter or getter is nontrivial
(not defined by attr_reader and others), but with attr_accessors there's
no use calling the setters and getters from within the same class,
accessing the variables directly is better.

TPR.
 
B

Bryan D

Assuming an attribute :field is defined, is there a processing
difference between using @field and self.field [within the defining
class?]  Does the ruby interpretter take a different path in yielding
the value depending how it is referenced?  I haven't notice anything.
I'm just curious if the interpretter takes extra steps when yielding
self.field.

Thanks

In terms of speed, it's very close, but using @field is slightly
faster, at least on my system.

Rehearsal -----------------------------------------------
using self: 4.640000 2.350000 6.990000 ( 7.032596)
using @: 4.550000 2.350000 6.900000 ( 6.928132)
------------------------------------- total: 13.890000sec

user system total real
using self: 4.660000 2.380000 7.040000 ( 7.137048)
using @: 4.570000 2.360000 6.930000 ( 7.075875)

Benchmark code:
require 'benchmark'

class Dummy
attr_reader :foo
def initialize
@foo = 7983.3435
end

def using_self
self.foo
end

def using_direct
@foo
end
end

n = 1000000
@d = Dummy.new
Benchmark.bmbm(7) do |x|
x.report("using self:") { n.times do @d.using_self; end }
x.report("using @:") { n.times do @d.using_direct; end }
end
 
D

dkmd_nielsen

Assuming an attribute :field is defined, is there a processing
difference between using @field and self.field [within the defining
class?]  Does the ruby interpretter take a different path in yielding
the value depending how it is referenced?  I haven't notice anything.
I'm just curious if the interpretter takes extra steps when yielding
self.field.

In terms of speed, it's very close, but using @field is slightly
faster, at least on my system.

Rehearsal -----------------------------------------------
using self:   4.640000   2.350000   6.990000 (  7.032596)
using @:      4.550000   2.350000   6.900000 (  6.928132)
------------------------------------- total: 13.890000sec

                  user     system      total        real
using self:   4.660000   2.380000   7.040000 (  7.137048)
using @:      4.570000   2.360000   6.930000 (  7.075875)

Benchmark code:
require 'benchmark'

class Dummy
  attr_reader :foo
  def initialize
    @foo = 7983.3435
  end

  def using_self
    self.foo
  end

  def using_direct
    @foo
  end
end

n = 1000000
@d = Dummy.new
Benchmark.bmbm(7) do |x|
  x.report("using self:") { n.times do @d.using_self;   end }
  x.report("using @:")    { n.times do @d.using_direct; end }
end

Thanks for the commentary, guys. This is the kind of stuff that is
useful to me. Most everything I do i very iterative. Fortunately, if
you can call it fortunate, most of my bottlenecks have nothing to do
with Ruby. Most of the time is I/O related stuff between servers.

Thanks again,
Happy Halloween
 
B

Brian Candler

dkmd_nielsen said:
Assuming an attribute :field is defined, is there a processing
difference between using @field and self.field [within the defining
class?]

Remember that you don't have to write "self.field" - "field" by itself
is fine, as long as you haven't assigned to a local variable called
"field" within the calling method.

def field
123
end

puts field # 123
field = 999
puts field # 999
puts field() # 123
puts self.field # 123
 

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

Members online

Forum statistics

Threads
474,197
Messages
2,571,041
Members
47,643
Latest member
ashutoshjha_1101

Latest Threads

Top