Making object methods available externally

ruby

    Next

  • 1. Global dynamic method definition
    From: Philippe Lang [mailto: XXXX@XXXXX.COM ] > As the code suggest, what I except is: > > B class init > B instance init > 123 > 456 > B instance init > 789 > > > > In other words, the global @@dynamic_method_outputs is not > cleared between D1 and D2 class definitions. Class variables are shared between a class and all its subclasses. You want an instance variable of the class itself: class B puts "B class init" def self.dynamic_method_outputs @dynamic_method_outputs ||= [] end def initialize puts "B instance init" end def self.add_to_dynamic_method_output(val) dynamic_method_outputs << val method_def = "def dynamic_method() " dynamic_method_outputs.each do |v| method_def << "puts #{v} \n" end method_def << "end" self.class_eval method_def end end class D1 < B add_to_dynamic_method_output 123 add_to_dynamic_method_output 456 end class D2 < B add_to_dynamic_method_output 789 end d1 = D1.new d1.dynamic_method d2 = D2.new d2.dynamic_method #=> B class init #=> B instance init #=> 123 #=> 456 #=> B instance init #=> 789
  • 2. Test::Unit runner for HTML output
    Is there a Test::Unit runner for HTML output? I'd like to keep this available on an internal Continuos Integration web page. (Ideally, I'd like to be able to tell the rake test tasks to use HTML output to a certain file, in addition to the standard stdout text output.)
  • 3. need a new Ruby book?
    Hi all, Back in 2001 or so I took a look at ruby...downloaded ruby for my windows machine, bought Thomas & Hunt's "Programming Ruby" (2001, Addison Wesley), ......and promptly got caught up in a massive career change. Now I am back with a bit of Java and mgmt experience under my belt and want to get back into ruby on my MacBook (with built in ruby 0.9 (02/07/03)) The question is, am i still good with this five year old book? At least for a while? Or should I consider it prime recycling material? My interest at this point is only personal and not professional...so I can't stick the employer with the bill. :P tia, Stu

Making object methods available externally

Postby David Stanford » Fri, 06 Feb 2009 03:37:30 GMT

Hi all,

I'm having trouble figuring out a way of creating a method within a
class that's available not only to the other object methods (object
instances), but also externally, as if I were to use 'self.method'.
Below is an (admittedly, lame) example of what I'm referring to:

#############################

class CheesePhrase
  def initialize(phrase)
    @phrase = phrase
    say_it
  end

  def say_it(phrase=@phrase)
    puts "#{phrase}"
  end
end

#############################

The above code works fine if I create an object instance, and (if I
choose to do so) call the method 'say_it', like so:

some_cheese_phrase = CheesePhrase.new("I like cheese.")
some_cheese_phrase.say_it

However, what if I'd also like to call the method directly, without
creating a new instance? For example, simply with:

CheesePhrase.say_it("I like cheese, too.")

I can't do this without using 'self.say_it' in the method declaration.
Though, if I do that, I am no longer able to call the method in
'initialize' since 'self.say_it' is now a class method. I get the
following error:

NoMethodError: undefined method `say_it' for #<CheesePhrase:0x284372f4
@phrase="I like cheese">
        from (irb):4:in `initialize'
        from (irb):11:in `new'

I'm sure I must be doing something wrong, or my concept of how to
implement this is totally wrong. The only other thought I've had is to
create duplicate methods, but this seems to violate the famed DRY
principle. Any advice would be much appreciated.

Thanks in advance!

-David
-- 
Posted via  http://www.**--****.com/ 


Re: Making object methods available externally

Postby Rob Biedenharn » Fri, 06 Feb 2009 03:52:38 GMT




class CheesePhrase
   def initialize(phrase)
     @phrase = phrase
     say_it
   end

   def self.say_it(phrase)
     puts phrase
   end
   def say_it
     self.class.say_it(@phrase)
   end
end

irb> some_cheese_phrase = CheesePhrase.new("I like cheese.")
I like cheese.
=> #<CheesePhrase:0x629d0 @phrase="I like cheese.">
irb> some_cheese_phrase.say_it
I like cheese.
=> nil
irb> CheesePhrase.say_it("I like cheese, too.")
I like cheese, too.
=> nil

-Rob

Rob Biedenharn		 http://www.**--****.com/ 
 XXXX@XXXXX.COM 



Re: Making object methods available externally

Postby David Stanford » Fri, 06 Feb 2009 04:03:55 GMT







Thanks a lot, Rob. Is this really the standard way of implementing 
something like this? It just seems a little redundant, no?

Thanks!

-David
-- 
Posted via  http://www.**--****.com/ 


Re: Making object methods available externally

Postby tjnogueira » Fri, 06 Feb 2009 05:04:12 GMT

Hi David, 
i don't understand well what you need. Is this that you are looking for:
class CheesePhrase 
  def initialize(phrase) 
    @phrase = phrase 
    CheesePhrase.say_it(phrase) 
  end
  def CheesePhrase.say_it(phrase=@phrase) 
    puts "#{phrase}"
  end 
end 

a = CheesePhrase.new('I like cheese')
a = CheesePhrase.say_it('I like too much cheese);

On Thu, 5 Feb 2009 03:37:30 +0900, David Stanford < XXXX@XXXXX.COM >





Re: Making object methods available externally

Postby Rob Biedenharn » Fri, 06 Feb 2009 05:06:55 GMT








When you need it, yes. However, it isn't typical that you'd do  
something like this.  Either the method belongs on the instance or it  
belongs on the class itself.  Occasionally, for convenience, you want  
a class method to be called on an instance and then you'd likely do it  
this way. Your example is simple (and, being an example, somewhat  
contrived), but illustrates a point.  You can call #say_it with no  
parameter because the instance variable is there so an instance  
*knows* what to say, but to call .say_it on the class, you need to  
pass the parameter.

-Rob

Rob Biedenharn		 http://www.**--****.com/ 
 XXXX@XXXXX.COM 




Re: Making object methods available externally

Postby Rick DeNatale » Fri, 06 Feb 2009 06:04:36 GMT

[Note:  parts of this message were removed to make it a legal post.]

On Wed, Feb 4, 2009 at 3:06 PM, Rob Biedenharn




Ruby does have a method Module#module_function which can be used in cases
similar to this. For a rather silly example:

module Test
  def foo
    puts "Foo"
  end

  module_function :foo
end

Test.foo

begin
  foo
rescue Exception => ex
  puts "oops! #{ex}"
end

self.extend Test
foo

when run produces:

Foo
oops! undefined local variable or method `foo' for main:Object
Foo

What module_function does is to copy one or more instance methods and make
them singleton methods of the module.  It only works for modules not
classes.

The canonical use case is in the Math module so that you can either write:

Math.sin(.2)

or

class X
   include Math

   def compute(val)
        2 + sin(val)
   end
end
-- 
Rick DeNatale

Blog:  http://www.**--****.com/ 
Twitter:  http://www.**--****.com/ 


Re: Making object methods available externally

Postby Julian Leviston » Fri, 06 Feb 2009 09:35:33 GMT

Put "self." in front of the method name in it's definition. This is  
called a class method. If you need both, have both.

Blog:  http://www.**--****.com/ 
Learn rails:  http://www.**--****.com/ 






Re: Making object methods available externally

Postby David Stanford » Sat, 07 Feb 2009 07:31:25 GMT

Thanks for all the responses, guys.

Judging from everyone's response, it sounds like what I'm trying to do 
isn't typically done. My mindset was, first, to simply create a standard 
class. While creating one of the object methods for that class, I 
realized that the same method code would be useful to call directly, 
without having to create an object instance; so, as I said, I was 
thinking there must be some way to do this, without repeating the same 
(or a similar piece) of code somewhere else.

So, thanks again!
-- 
Posted via  http://www.**--****.com/ 


Re: Making object methods available externally

Postby Mike Gold » Sat, 07 Feb 2009 23:50:08 GMT



To make a minor point, I see this use of module_function often, even in 
the standard library.  I don't like it.

In addition to the module_function method, there's the module_function 
scoping state, like public or private or protected, which is likewise 
enabled by calling module_function without arguments.  Therefore we can 
make a D.R.Y. equivalent:

module Test
  module_function

  def foo
    puts "Foo"
  end
end
-- 
Posted via  http://www.**--****.com/ 


Re: Making object methods available externally

Postby Robert Klemme » Sat, 07 Feb 2009 23:58:43 GMT

2009/2/5 David Stanford < XXXX@XXXXX.COM >:


Agreed.


In that case I would have the method definition *only* at class level
since apparently it is independent of instance state.  I wouldn't even
have it as instance method at all.  That avoids confusion.  If you
need to invoke the method from instance methods the
self.class.a_method() idiom works well IMHO.

Kind regards

robert

-- 
remember.guy do |as, often| as.you_can - without end


Re: Making object methods available externally

Postby Roger Pack » Sun, 08 Feb 2009 23:24:09 GMT



you could do something like
module X
 def shared_method
 end
end
class Y
 include X
 extend X
end
?
-=r
-- 
Posted via  http://www.**--****.com/ 


Re: Making object methods available externally

Postby Gregory Brown » Sun, 08 Feb 2009 23:41:08 GMT



Probably s bit extreme for one method, but say you had 10 you wanted
to do this with:

module Foo
  def self.included(base)
     base.extend(self)
  end

  def method1; end
  def method2; end
  #...
end

class A
  include Foo # no need for manual extend call
end

Not tested or necessarily recommended. :)

-greg

-- 
Technical Blaag at:  http://www.**--****.com/ 
 Non-tech stuff at:  http://www.**--****.com/ 
"Ruby Best Practices"  Book now in O'Reilly Roughcuts:
 http://www.**--****.com/ 


Re: Making object methods available externally

Postby Christopher Dicely » Mon, 09 Feb 2009 00:42:05 GMT

On Fri, Feb 6, 2009 at 6:58 AM, Robert Klemme




I think that depends on why the method is useful at both places; one
thing I've seen occasionally is the use case where it is useful at the
class level because there are lots of times you'd like to create an
instance, call the method, and then be done with the instance, so it
makes sense to have something like:

class Foo
  def initialize(init_arg1, ..., init_argn)
    # setup
  end

  def action(action_arg1, ..., action_argn)
    # do the action
  end

  def self.action(init_arg1, ..., init_argn, action_arg1, ..., action_argn)
    new(init_arg1, ..., init_argn).action(action_arg1, ..., action_argn)
  end
end

If that's the reason, using the CheesePhrase example:

class CheesePhrase
  # all the stuff in the original example
  def self.say_it(phrase)
    new(phrase).say_it
  end
end


Re: Making object methods available externally

Postby Simon Krahnke » Mon, 09 Feb 2009 04:20:54 GMT

* David Stanford < XXXX@XXXXX.COM > (2009-02-04) schrieb:







Where do you see the redundancy? Nothing is repeated.

mfg,                   simon .... l

Similar Threads:

1.Making an object follow another object - FAIL!

2.Creating an object the hard way, made easy with lambda

#!/usr/bin/env ruby
#$LastChangedRevision: 49 $

# The purpose of this sample is to demonstrate the application of
lambda
# expressions to create a rudimentary 'person object'.
#
# Its features Smalltalk style "message passing" and "variables are
private,
# methods are public" encapsulation.
#
# This sample is an approximation, and drastic simplification, of many
of the
# examples you find written in Scheme, as it does not provide an OO
system for
# use by the developer.
#
# This is OK, though, since the point of this example is only to
demonstrate
# one application of lambda expressions. You may use them to write
your own
# object system in Ruby, but then again why bother, Ruby has already
got
# what you need!

def get_abstract_person_object
    first_name = ""
	last_name = ""
	age = -1
	my_to_s = lambda {
        "FIRST NAME:'#{first_name}', LAST NAME:'#{last_name}',
AGE:'#{age}'\n"
	}
	new = lambda { |fn, ln, ag|
        first_name = fn
        last_name = ln
        age = ag
        nil
    }

	lambda { |msg|

		result = nil

		case msg[0]
            when :new
                new.call(msg[1], msg[2], msg[3])
			when :get_first_name
				result = first_name
			when :set_first_name
				result = first_name = msg[1]
			when :get_last_name
				result = last_name
			when :set_last_name
				result = last_name = msg[1]
			when :get_age
				result = lage
			when :set_age
				result = age = msg[1]
			when :to_s
				result = my_to_s.call
		end

		if result != nil
			result
		else
			"MESSAGE '#{msg[0]}' NOT UNDERSTOOD!"
		end
	}
end

kristy = get_abstract_person_object
puts "Create Kristy"
puts kristy.call([:to_s])
kristy.call([:set_first_name, "Kristy"])
kristy.call([:set_last_name, "T"])
kristy.call([:set_age, 27])
puts kristy.call([:to_s])

puts "Create Steve"
steve = get_abstract_person_object
steve.call([:set_first_name, "Steve"])
steve.call([:set_last_name, "M"])
steve.call([:set_age, 48])
puts steve.call([:to_s])

puts
puts "Are the two 'objects' really different entities? YES.\n"
puts kristy.call([:to_s])
puts steve.call([:to_s])

puts
puts "What happens when you send a message that the object does not
understand?"
puts kristy.call([:foo])

puts
puts "A \"constructor\" message"
dave = get_abstract_person_object
dave.call([:new, "David", "O", 28])
puts dave.call([:to_s])

3.accessing one objects methods from within another object

4.Accessing class variables in method made using define_method

I want to use class variables and have them accessible from class  
methods that have been defined outside of the class using  
define_method or something similar.  When I try this the class  
variable isn't in scope.  A simple test case is:

class A
	@@aa = 20
end

A.class_eval {define_method(:foo){puts @aa}}

a = A.new
a.foo			=> nil and not 20 as expected

or using

A.send(:define_method, :foo){puts @aa}
a.foo			=> nil and not 20 as expected

gives the same result but

class A
	def foo
		puts @@aa
	end
end

a.foo			=> 20 as expected.

How do I get the same behaviour as opening the class and defining the  
method normally?

Thanks,

Dave.





5.Using object methods of first module in methods of second module

Beforehand sorry for my English, I'm from Russia.

I have 2 modules:

module SendMail
  def self.send_mail(hash)
    # some code
  end
end

module ActionMailer
  def quoted_printable(text, charset)
    # some code
  end
end

Please say me, is there any way to have access to method
"quoted_printable" of module ActionMailer from method send_mail of
module SendMail. It would be good, if I pass using Classes in this
situation, because I want to divide
namespaces correctly.

6. Method name to method object

7. RCR: def method...end return a method object.

8. Private methods - only available to oneself?



Return to ruby

 

Who is online

Users browsing this forum: No registered users and 36 guest