Calling methods, beginner help

Hello G.s,

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…

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

Ronnie Aa wrote in post #995566:

Hello G.s,

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 ‘toplevel’ just like you did. However, a method defined at the
toplevel 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. Because product() is a private method, the
only way you can call product is like this:

product()

So you would have to pass the array as an argument to the product()
method:

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

puts product([1, 2, 3])

–output:–
6

Or, like this:

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

class Dog
def do_stuff(an_array)
product(an_array)
end
end

d = Dog.new
puts d.do_stuff([1, 2, 3])

–output:–
6

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

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

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.

Program background == 4 weeks ruby

Thanx for your suggestion I’ll read that… and come back later if
necessary…

Hi Brain,

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

Thank you!

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

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.

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.

Ronnie Aa wrote in post #995728:

With procedures I mean this:

class Proc - RDoc Documentation.

‘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@:2(irb)

lambda { puts “hello” }
=> #Proc:0x00007fdbc6ec4f10@:3(irb)

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

Brian C. 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:

class Proc - RDoc Documentation.

‘Proc’ is a abbreviation of procedure isn’t it?

Thnx for your help and the information,

Ronnie

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.

~