Some newbie questions

I got some newbie questions which I would very much appreciate if
someone could answer (in a way that a newbie would understand):

1. What does @ mean in Ruby? Im sure I have seen variables like this:
@variable. A new datatype like the :symbol perhaps?

2. Hash.new {0}
   anotherhash.values.each {|x| thecreatedhash[x] += 1}

What makes the hash created above different from a hash created the
normal way? I can execute the block on a hash created with that method
but not a normal empty hash created manually.

3. Is there any difference using Dir.entries "the directory"
compared to using
Dir.glob "*" if you use them on the same directory?

Thanks in advance!

···

--
Posted via http://www.ruby-forum.com/.

Vladimir Van Bauenhoffer wrote in post #1022210:

I got some newbie questions which I would very much appreciate if
someone could answer (in a way that a newbie would understand):

1. What does @ mean in Ruby? Im sure I have seen variables like this:
@variable. A new datatype like the :symbol perhaps?

The @ means that the variable is an object variable, its scope is
within, and is associated to, the current object.

For example,

class Person
  def initialize(name)
       @name=name
  end

  def say_your_name
       puts @name
  end

In this class, you assign the name provided to the class to @name.
@name as an object variable, is then accessible from any other method
inside the object.

···

--
Posted via http://www.ruby-forum.com/\.

What exactly do you mean by "the normal way"?

···

On Fri, Sep 16, 2011 at 04:46:28AM +0900, Vladimir Van Bauenhoffer wrote:

2. Hash.new {0}
   anotherhash.values.each {|x| thecreatedhash += 1}

What makes the hash created above different from a hash created the
normal way? I can execute the block on a hash created with that method
but not a normal empty hash created manually.

--
Chad Perrin [ original content licensed OWL: http://owl.apotheon.org ]

A hash created via a literal:

  hash1 = {}

has a default value of nil:

  hash1['foo'] # returns nil

A hash created as you suggested:

  hash2 = Hash.new { 0 }

*computes* a value whenever the key lookup fails. In this case the computation
is the trivial expression: 0 but it could be something arbitrarily complicated
and can depend on the key itself

  hash3 = Hash.new { |hash, key| hash[key] = key.reverse }
  hash3['hello'] # returns 'olleh'

If you want the returned value to be saved for future lookups with the same key,
then you have to store the value in the hash explicitly as shown above. Otherwise
a new value will be recomputed for each key lookup (even for multiple lookups of
the same key).

If you just want a hash that defaults to 0 for missing keys then you don't really
need the block form where you 'compute' zero each time. Use this form instead:

  hash4 = Hash.new(0)
  hash4[42] # returns 0

Be careful with this form though because it is the exact same object that is
returned for the value of *all* missing keys:

  hash5 = Hash.new() # an array is allocated here and used for all missing keys
  apple = hash5['apple'] # the array allocated and passed to Hash.new
  banana = hash5[banana'] # the same array!

  apple.equal?(banana) # true

In this case, you almost always want to allocate a brand new array for each
key miss. Time to go back to the block format:

  hash6 = Hash.new {|h,k| h[k] = } # allocate a brand new array for each key miss

Gary Wright

···

On Sep 15, 2011, at 3:46 PM, Vladimir Van Bauenhoffer wrote:

2. Hash.new {0}
  anotherhash.values.each {|x| thecreatedhash += 1}

What makes the hash created above different from a hash created the
normal way? I can execute the block on a hash created with that method
but not a normal empty hash created manually.

1. What does @ mean in Ruby? Im sure I have seen variables like this:
@variable. A new datatype like the :symbol perhaps?

Someone beat me to this one, so I'll just preemptively add, @@ means
it's a class variable.

2. Hash.new {0}
anotherhash.values.each {|x| thecreatedhash += 1}

What makes the hash created above different from a hash created the
normal way? I can execute the block on a hash created with that method
but not a normal empty hash created manually.

You've already clarified that "normal" means {}. But what I don't get
is how you're using it. Do you mean that:

  thecreatedhash = Hash.new {0}
  anotherhash.values.each {|x| thecreatedhash += 1}

yields different results from:

  thecreatedhash = {}
  anotherhash.values.each {|x| thecreatedhash += 1}

? That boils down to the difference between "Hash.new {0}" and "{}".
The latter will return an empty hash such that uninitialized slots
have a nil value, as usual. The former is a good bit more
complicated. There is documentation at:

  class Hash - RDoc Documentation

At first glance the docs would lead me to believe that the
uninitialized slots should return the value {0}, using the
Hash.new(object) syntax, but the braces in fact make it take that as a
code block, even though it's not using the args, so it's using the
third syntax (Hash.new {|hash, key| block }). This means it returns
0, the result of that code block, for all uninitialized slots.
Occasional confusion between hashes and code blocks is one of the
subtleties of Ruby.

So, in the former case, anotherhash would cause corresponding slots of
thecreatedhash to be set to 1, because they start at 0 and get
incremented. In the latter, they'd start as nil, and you can't add 1
to that, so you'd get a NoMethodError. Is ths the behavior you're
seeing?

-Dave

···

On Thu, Sep 15, 2011 at 15:46, Vladimir Van Bauenhoffer <cluny_gisslaren@hotmail.com> wrote:

--
LOOKING FOR WORK, preferably Ruby on Rails, in NoVa/DC; see main web site.
Main Web Site: davearonson.com
Programming Blog: codosaur.us
Excellence Blog: dare2xl.com

3. Is there any difference using Dir.entries "the directory"
compared to using
Dir.glob "*" if you use them on the same directory?

Yes. Dir.glob '*' will not return Unix-style hidden files (files that
start with a dot).

Example:
sampledir
>-- .
>-- ..
>-- foo.txt
>-- .bar.txt

Dir.glob("*") #=> ['foo.txt'] #if Dir.pwd = sampledir
Dir.entries('sampledir') #=> ['.', '..', 'foo.txt', '.bar.txt']

Thanks for all the helpful answers.

Regarding the first question about @-variables: if I understood it
correctly it simply makes it so that the variable can be used anywhere
within the class and is not limited by variable scopes as long as it is
used within the class. Correct?

···

--
Posted via http://www.ruby-forum.com/.

alberto kaputchella wrote in post #1022215:

Vladimir Van Bauenhoffer wrote in post #1022210:

I got some newbie questions which I would very much appreciate if
someone could answer (in a way that a newbie would understand):

1. What does @ mean in Ruby? Im sure I have seen variables like this:
@variable. A new datatype like the :symbol perhaps?

The @ means that the variable is an object variable, its scope is
within, and is associated to, the current object.

For example,

class Person
  def initialize(name)
       @name=name
  end

  def say_your_name
       puts @name
  end

In this class, you assign the name provided to the class to @name.
@name as an object variable, is then accessible from any other method
inside the object.

Thanks for answering that question. In Python (the only other language I
know a little of) you dont have to do anything special with the name
when you make an object. I wonder why it's like that in Ruby.

···

--
Posted via http://www.ruby-forum.com/\.

alberto kaputchella:

The @ means that the variable is an object variable, its scope is
within, and is associated to, the current object.

For example,

class Person
  def initialize(name)
       @name=name
  end

  def say_your_name
       puts @name
  end

In this class, you assign the name provided to the class to @name.
@name as an object variable, is then accessible from any other method
inside the object.

So the @-sign in Ruby is like self in Python? Can someone confirm who
knows Python?

Chad Perrin:

What exactly do you mean by "the normal way"?

I meant like this: myhash = {}, sorry for being unclear.

···

--
Posted via http://www.ruby-forum.com/\.

Unless you ask it to:

irb(main):001:0> Dir['*']
=> ["Applications", "Code", "cookies.txt", "Desktop", "Documents", "Downloads", "git.tar.gz", "Library", "Movies", "Music", "Pictures", "Public", "Sites", "tmp", "Zeraw"]

irb(main):002:0> Dir['.*']
=> [".", "..", ".adobe", ".autotest", ".bash_history", ".bundler", ".CFUserTextEncoding", ".config", ".cups", ".DS_Store", ".dvdcss", ".editrocket", ".fontconfig", ".gdb_history", ".gem", ".gitconfig", ".gitk", ".gnome2", ".inkscape-etc", ".irb-history", ".irb_history", ".lesshst", ".MacOSX", ".monk", ".profile", ".psql_history", ".recently-used.xbel", ".ri", ".rs", ".rvm", ".rvmrc", ".sqlite_history", ".ssh", ".subversion", ".Trash", ".viminfo", ".Xauthority", ".Xcode"]

···

On Sep 16, 2011, at 12:49 AM, Gunther Diemant wrote:

3. Is there any difference using Dir.entries "the directory"
compared to using
Dir.glob "*" if you use them on the same directory?

Yes. Dir.glob '*' will not return Unix-style hidden files (files that
start with a dot).

Yes.

-- Matma Rex

···

2011/9/16 Vladimir Van Bauenhoffer <cluny_gisslaren@hotmail.com>:

Regarding the first question about @-variables: if I understood it
correctly it simply makes it so that the variable can be used anywhere
within the class and is not limited by variable scopes as long as it is
used within the class. Correct?

alberto kaputchella:

The @ means that the variable is an object variable, its scope is
within, and is associated to, the current object.

For example,

class Person
def initialize(name)
@name=name
end

def say_your_name
puts @name
end

In this class, you assign the name provided to the class to @name.

Not to the class - to the _instance_! Or more precisely the name is
passed to Person#new which forwards it to #initialize after allocating
the instance.

@name as an object variable, is then accessible from any other method
inside the object.

So the @-sign in Ruby is like self in Python? Can someone confirm who
knows Python?

I do not know Python but I assume "self" in Python is the same as
"self" in Ruby: a reference to the current object.

Variable names prefixed with @ really set the scope of the variable to
be the instance and not the current method. "@foo" is an instance
variable of whatever self is at the moment and "foo" is a local
variable. I suggest you play around with these a bit - I am sure you
will quickly notice the difference.

Chad Perrin:

What exactly do you mean by "the normal way"?

I meant like this: myhash = {}, sorry for being unclear.

myhash = {} is the same as myhash = Hash.new - only less typing.

Kind regards

robert

···

On Thu, Sep 15, 2011 at 10:57 PM, Vladimir Van Bauenhoffer <cluny_gisslaren@hotmail.com> wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

So the @-sign in Ruby is like self in Python? Can someone confirm who
knows Python?

Not so much. Much like Python, Ruby classes deal with self as well. However in Ruby that's passed around behind the scenes, so you won't see it in method definitions. Take for example the following:

···

--------------------------------------

class Test:

... myvar = "This is a variable"
... def mymethod(self):
... return self.myvar
...

inst = Test()
inst.mymethod()

'This is a variable'
--------------------------------------

Here in this case, the instance of Test, `inst` is being passed in as "self" to mymethod. Now something to note is that here:

------------------------------------
myvar = "This is a variable"
------------------------------------

Has the same `self` as

------------------------------------
return self.myvar
------------------------------------

Now in Ruby, things are different. When defining classes, self inside the class definition can be referring to two different things. Take for example a copy of the above:

------------------------------------
irb(main):001:0> class Test
irb(main):002:1> @myvar = "This is a variable"
irb(main):003:1> def mymethod
irb(main):004:2> @myvar
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):007:0> inst = Test.new
=> #<Test:0x0000010202eb00>
irb(main):008:0> inst.mymethod
=> nil
irb(main):009:0>
------------------------------------

Noticed that mymethod returned nil. This is because `self` in the context of where @myvar is located is the CLASS ITSELF:

------------------------------------
irb(main):009:0> class Test
irb(main):010:1> p self
irb(main):011:1> @myvar = "This is a variable"
irb(main):012:1> def mymethod
irb(main):013:2> @myvar
irb(main):014:2> end
irb(main):015:1> end
Test
=> nil
-----------------------------------

That is because class definitions in Ruby are expressions that evaluate to the last statement of the class definition. In this case method definitions return nil, so that's the resulting value. We could change this however:

-----------------------------------
irb(main):018:0> class Test
irb(main):019:1> @myvar = "This is a variable"
irb(main):020:1> def mymethod
irb(main):021:2> @myvar
irb(main):022:2> end
irb(main):023:1> "return value"
irb(main):024:1> end
=> "return value"
-----------------------------------

Notice how in this case, a string value is the last statement, so that string becomes the result of the class definition. Now when we were calling mymethod from an instance, the instance itself is passed in to mymethod instead. This is a crucial difference between Ruby and Python in how classes are defined. If at any time you get confused as to how methods/variables are being accessed, check the value of self.

Regards,
Chris White
http://www.twitter.com/cwgem

There have already been some good answers to this, but I'll throw in
another formulation of the explanation:

    myhash = {:foo => 'foo'}
    mystring = 'foo'

This assigns a hash literal to myhash and a string literal to mystring.

    myhash = {}
    mystring = ''

This assigns an *empty* hash literal to myhash, and an *empty* string
literal to mystring. In the case of the hash, all attempts to access
hash keys return a value of nil.

    myhash = Hash.new
    mystring = String.new

This assigns an empty hash to myhash and an empty string to mystring much
as in the immediately previous case, but does so by explicitly using the
new constructor rather than explicit assignment of a hash literal and
string literal to their respective variable names.

    myhash = Hash.new(0)
    mystring = String.new('zero')

This assigns a hash to myhash whose default value for nonexistent strings
is 0, and a string to mystring whose value is 'zero'.

    myhash = Hash.new {|h,k| k.to_s }
    mystring = String.new { 'foo' }

This is where they diverge. You can pass a block to Hash.new telling it
what default values should be used for as-yet undefined keys. In this
case, with the hash (as h) and the key (as k) passed to the block as
parameters, myhash[:foo] will return 'foo'. In the case of this
construction for mystring, the block is thrown away, and you still get an
empty string.

···

On Fri, Sep 16, 2011 at 05:57:36AM +0900, Vladimir Van Bauenhoffer wrote:

Chad Perrin:
>
> What exactly do you mean by "the normal way"?

I meant like this: myhash = {}, sorry for being unclear.

--
Chad Perrin [ original content licensed OWL: http://owl.apotheon.org ]