calling methods, beginner help

R

Ronnie Aa

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..
 
M

Markus Schirp

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
 
7

7stud --

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()
 
R

Ronnie Aa

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
 
7

7stud --

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.
 
M

Markus Schirp

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

https://github.com/datamapper/dm-core

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 ;)
 
R

Ronnie Aa

Program background == 4 weeks ruby

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

Brian Candler

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.
 
B

Brian Candler

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.
 
B

Brian Candler

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 :) A Proc object can either be a block crystallised
into an object, or a lambda. It carries the semantics of either.

$ irb --simple-prompt=> #<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
 
S

Stu

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.

~
 

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

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,565
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top