Calling methods, beginner help

Hello Guys,

I'm fairly new to ruby and I have a question:

I have an array:

$xarray = [10,10]

I have this method:

def product

  inject(1) { |s, v| s *= v }

end#def

And I have a class:

class Test

     def initialize()

     tt= $xarray.product

     UI.messagebox tt

     end#def
end#class

I want to use the method 'product' in my class. How do I do that ??
Or more in general how do I define methods that I can use all through my
ruby script???

Thnx for your help..

···

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

Hello Ronnie,

When you want to add the method #product to the Array class you have to
explictly reopen the class.

Example:

···

-------

class Array
  def product
    inject(1) { |s, v| s *= v }
  end
end

Now you could call #product on Array instances.

[1,2].product # => 2

But:
----

(Monkey-)Patching core classes (like Array) is normaly a bad thing!
It adds more problems than it solves!

An better example for your use case would be:

class Test
  def initialize
    @array = [10,10]
  end

  def product
    @array.inject(1) { |s,v| s *= v }
  end
end

In this case product is defined as an instance method of your own Test
class (not as an instance method of array).

You could call product this way:

object = Test.new
object.product # => 100

--

Markus

On Fri, Apr 29, 2011 at 02:06:13AM +0900, Ronnie Aa wrote:

Hello Guys,

I'm fairly new to ruby and I have a question:

I have an array:

$xarray = [10,10]

I have this method:

def product

  inject(1) { |s, v| s *= v }

end#def

And I have a class:

class Test

     def initialize()

     tt= $xarray.product

     UI.messagebox tt

     end#def
end#class

I want to use the method 'product' in my class. How do I do that ??
Or more in general how do I define methods that I can use all through my
ruby script???

Thnx for your help..

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

Ronnie Aa wrote in post #995566:

Hello Guys,

I'm fairly new to ruby and I have a question:

I have an array:

$xarray = [10,10]

Don't EVER use global variables. Never, ever, ever, never.

I have this method:

def product

  inject(1) { |s, v| s *= v }

end#def

And I have a class:

class Test

     def initialize()

     tt= $xarray.product

     UI.messagebox tt

     end#def
end#class

I want to use the method 'product' in my class. How do I do that ??
Or more in general how do I define methods that I can use all through my
ruby script???

If you want to use a method anywhere in your program, then you define it
at the 'top level' just like you did. However, a method defined at the
top level is a private method, and a private method cannot be called
with a 'receiver', for instance in this line:

$xarray.product

$xarray is the receiver. The only way you can call the product() method
is like this:

product()

···

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

Thanx for your answers. I know: never use global variables ... and no
monkey patching ...I'll try.

I'm programming for sketchup api. My code structure is like this

module Module

class Do_this
def initialize()
end;end;

class Do_that
def initialize()
end;end;

#When I want to execute a command I have to add a button in the GUI of
Sketchup, like this:

cmd = UI::Command.new("Do this") {Module::Do_this.new()}
UI.menu("Plugins").add_item(cmd)

end#module

···

#-------------------------------------------------------
So as markus suggested

class Test
  def initialize
    @array = [10,10]
  end

  def product
    @array.inject(1) { |s,v| s *= v }
  end
end

And than run *outside* the class:

object = Test.new
object.product # => 100

Is in my case impossible: it has to run *inside* a class

Just did some quick reading about procs, is that an option???

For extra clearness:

My class Do_this and my class Do_that both have to use that method..
They both use the same variable and both have to apply the same
operations on that variable (amongst other things of course)..

Please help

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

Program background == 4 weeks ruby

Thanx for your suggestion I'll read that... and come back later if
necessary..

···

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

Hi Brain,

Now I see, this is what i was looking/hoping for...

Thank you!

···

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

Ronnie Aa wrote in post #995580:

Thanx for your answers. I know: never use global variables ... and no
monkey patching ...I'll try.

Whoa, you can use monkey patching if you follow some guidelines.

I'm programming for sketchup api. My code structure is like this

module Module

class Do_this
def initialize()
end;end;

class Do_that
def initialize()
end;end;

The formatting and lack of indenting you are using is unacceptable.

#When I want to execute a command I have to add a button in the GUI of
Sketchup, like this:

cmd = UI::Command.new("Do this") {Module::Do_this.new()}
UI.menu("Plugins").add_item(cmd)

end#module
#-------------------------------------------------------
So as markus suggested

class Test
  def initialize
    @array = [10,10]
  end

  def product
    @array.inject(1) { |s,v| s *= v }
  end
end

And than run *outside* the class:

object = Test.new
object.product # => 100

Is in my case impossible: it has to run *inside* a class

What does that mean?

Just did some quick reading about procs, is that an option???

For extra clearness:

My class Do_this and my class Do_that both have to use that method..
They both use the same variable and both have to apply the same
operations on that variable (amongst other things of course)..

Please help

It sounds like you are trying to reinvent someone's wheel. Anything you
are trying to do has already been done before--or you are going about it
the wrong way.

···

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

Hola,

Since I see you got a programming background, but you are *just* new
to ruby, I'd suggest you should read some code from guys with IMHO
*very* good ruby coding style. (not mine *g*)

Try to read code from a random advanced ruby library,
most of your questions about API-Design will be answered!

You can start with one of my favorite libraries: datamapper

I did not got the point in your code so I cannot help you without a
better description about what you are trying to do :wink:

···

--

Markus

On Fri, Apr 29, 2011 at 02:44:31AM +0900, Ronnie Aa wrote:

Thanx for your answers. I know: never use global variables ... and no
monkey patching ...I'll try.

I'm programming for sketchup api. My code structure is like this

module Module

class Do_this
def initialize()
end;end;

class Do_that
def initialize()
end;end;

#When I want to execute a command I have to add a button in the GUI of
Sketchup, like this:

cmd = UI::Command.new("Do this") {Module::Do_this.new()}
UI.menu("Plugins").add_item(cmd)

end#module
#-------------------------------------------------------
So as markus suggested

class Test
  def initialize
    @array = [10,10]
  end

  def product
    @array.inject(1) { |s,v| s *= v }
  end
end

And than run *outside* the class:

object = Test.new
object.product # => 100

Is in my case impossible: it has to run *inside* a class

Just did some quick reading about procs, is that an option???

For extra clearness:

My class Do_this and my class Do_that both have to use that method..
They both use the same variable and both have to apply the same
operations on that variable (amongst other things of course)..

Please help

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

Ronnie Aa wrote in post #995580:

For extra clearness:

My class Do_this and my class Do_that both have to use that method..
They both use the same variable and both have to apply the same
operations on that variable (amongst other things of course)..

One way to share common code is using a module, and including it into
those classes where you need it.

module MyUsefulMethods
  def product
    @foo.inject { |x,y| x*y }
  end
end

class DoThis
  include MyUsefulMethods
  def initialize
    @foo = [1,2,3]
  end
end

class DoThat
  include MyUsefulMethods
  def initialize
    @foo = [4,5,6]
  end
end

p DoThis.new.product
p DoThat.new.product

Note that I'm using an instance variable (@foo) not a global variable
($foo). Each instance of those classes has its own @foo.

···

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

Ronnie Aa wrote in post #995637:

Could this problem be solved with a procedure also???

There are no procedures in Ruby - only methods.

If you want a standalone method, which doesn't really belong to any
particular object instance, IMO the cleanest way is to make it a module
method:

module Util
  def self.product(arr)
    arr.inject { |x,y| x*y }
  end
end

p Util.product([1,2,3])

(Of course, Util is an instance of class Module, so the method *does*
actually belong to an object instance. The module is just a useful place
to hang the method onto with its own namespace)

Then you can put this module into a separate file, util.rb, and it's
easy to re-use from other code.

There is a slightly different syntax which you will occasionally come
across:

module Util
  def product(arr)
    arr.inject { |x,y| x*y }
  end
  module_function :product
end

# Now you can can call Util.product, but you can also mix the Util
# module into your own classes.

class Foo
  include Util
  def doit(arr)
    product(arr)
  end
end

p Util.product([1,2,3]) # => 6
p Foo.new.doit([4,5,6]) # => 120

Incidentally, a really good source of info on Ruby is
http://www.ruby-doc.org/docs/ProgrammingRuby/
This is the free 1st edition, which is old but still relevant. You can
also buy fthe 2nd edition for ruby 1.8, or the 3rd edition for ruby 1.9,
in paper or PDF form.

Regards,

Brian.

···

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

Brian Candler wrote in post #995710:

Ronnie Aa wrote in post #995637:

Could this problem be solved with a procedure also???

There are no procedures in Ruby - only methods.

With procedures I mean this:

http://www.ruby-doc.org/core/classes/Proc.html\.

'Proc' is a abbreviation of procedure isn't it?

Thnx for your help and the information,

Ronnie

···

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

Ronnie Aa wrote in post #995728:

With procedures I mean this:

http://www.ruby-doc.org/core/classes/Proc.html\.

'Proc' is a abbreviation of procedure isn't it?

No, it's a Proc :slight_smile: A Proc object can either be a block crystallised
into an object, or a lambda. It carries the semantics of either.

$ irb --simple-prompt

def foo(&blk); blk; end

=> nil

foo { puts "hello" }

=> #<Proc:0x00007fdbc6eceba0@(irb):2>

lambda { puts "hello" }

=> #<Proc:0x00007fdbc6ec4f10@(irb):3>

You probably don't want to concern yourself with the differences, but
the gory details are here:
http://innig.net/software/ruby/closures-in-ruby.rb

···

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

The etymology of Proc and proc is procedure. The word Procedure is
pretty generic in terms. It can mean method, function, routine, and
subroutine. It's definition is a set of instructions independent from
main. From a procedural programming point of view everything called
from main is a procedure.

In ruby main is an object so therefor everything called inside main is
a method call.

Ruby doesn't really have functions inherently since the last statement
of instructions always implicitly returns a value even if it's thrown
away on the level of the caller. To make it more interesting Proc.new
returns an object of the function so it could potentially be called a
function object (i.e.functor).

But these are really semantics. Knowing how Proc.new and lambda differ
are more important than where the name of the constructor came from as
it could have easily been named Block.new

Brian Cander's link to closures-in-ruby.rb is a really well documented
read on the idiosyncrasies and form of functional programming inside
ruby.

···

~

On Fri, Apr 29, 2011 at 4:27 AM, Ronnie Aa <liquid98@gmail.com> wrote:

Brian Candler wrote in post #995710:

Ronnie Aa wrote in post #995637:

Could this problem be solved with a procedure also???

There are no procedures in Ruby - only methods.

With procedures I mean this:

http://www.ruby-doc.org/core/classes/Proc.html\.

'Proc' is a abbreviation of procedure isn't it?

Thnx for your help and the information,

Ronnie

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