execute a method in a ruby file - ruby

I have this dummy ruby class file (Bar.rb):
class Bar
foo() # execute foo()
def foo()
puts "Hello world, "
end
end
And I ran the file with:
$ ruby Bar.rb
I was expecting to see "Hello, world" in the command, but got this error:
undefined local variable or method `foo' for Bar:Class (NameError)
from bar.rb:3:in `<main>'
So how do I execute a method? Does Ruby have any main method (as in Java or C/C++)?

A couple of reasons this doesn't work as you have written it.
The method foo hasn't been declared before you attempt to call it.
The method foo, as you have declared it, is an instance method. You're not invoking it on an instance of the class.
This would work:
class Bar
def self.foo
end
foo
end
As others have said, though, you probably don't need to wrap this in a class.

You don't need any class, you can call any methods you like right from the file itself:
bar.rb:
puts "Hello, world!"
If you want to stick with your code, you are calling foo before its declaration, which obviously doesn't work.

First you define the method, then you call it.
No need for a main procedure, the first code outside a class or method will be executed first. The script itself is the main. I'm sure there are better definitions for this, but i'm sure you will underdstand.
def foo()
puts "Hello world, "
end
foo() # execute
Also no need to put this in a class, then you would have to initiate her first.
class Bar
def foo()
puts "Hello world, "
end
end
bar = Bar.new
bar.foo

Related

Monkey patch ruby instance method, using the original definition? [duplicate]

Say I am monkey patching a method in a class, how could I call the overridden method from the overriding method? I.e. Something a bit like super
E.g.
class Foo
def bar()
"Hello"
end
end
class Foo
def bar()
super() + " World"
end
end
>> Foo.new.bar == "Hello World"
EDIT: It has been 9 years since I originally wrote this answer, and it deserves some cosmetic surgery to keep it current.
You can see the last version before the edit here.
You can’t call the overwritten method by name or keyword. That’s one of the many reasons why monkey patching should be avoided and inheritance be preferred instead, since obviously you can call the overridden method.
Avoiding Monkey Patching
Inheritance
So, if at all possible, you should prefer something like this:
class Foo
def bar
'Hello'
end
end
class ExtendedFoo < Foo
def bar
super + ' World'
end
end
ExtendedFoo.new.bar # => 'Hello World'
This works, if you control creation of the Foo objects. Just change every place which creates a Foo to instead create an ExtendedFoo. This works even better if you use the Dependency Injection Design Pattern, the Factory Method Design Pattern, the Abstract Factory Design Pattern or something along those lines, because in that case, there is only place you need to change.
Delegation
If you do not control creation of the Foo objects, for example because they are created by a framework that is outside of your control (like ruby-on-rails for example), then you could use the Wrapper Design Pattern:
require 'delegate'
class Foo
def bar
'Hello'
end
end
class WrappedFoo < DelegateClass(Foo)
def initialize(wrapped_foo)
super
end
def bar
super + ' World'
end
end
foo = Foo.new # this is not actually in your code, it comes from somewhere else
wrapped_foo = WrappedFoo.new(foo) # this is under your control
wrapped_foo.bar # => 'Hello World'
Basically, at the boundary of the system, where the Foo object comes into your code, you wrap it into another object, and then use that object instead of the original one everywhere else in your code.
This uses the Object#DelegateClass helper method from the delegate library in the stdlib.
“Clean” Monkey Patching
Module#prepend: Mixin Prepending
The two methods above require changing the system to avoid monkey patching. This section shows the preferred and least invasive method of monkey patching, should changing the system not be an option.
Module#prepend was added to support more or less exactly this use case. Module#prepend does the same thing as Module#include, except it mixes in the mixin directly below the class:
class Foo
def bar
'Hello'
end
end
module FooExtensions
def bar
super + ' World'
end
end
class Foo
prepend FooExtensions
end
Foo.new.bar # => 'Hello World'
Note: I also wrote a little bit about Module#prepend in this question: Ruby module prepend vs derivation
Mixin Inheritance (broken)
I have seen some people try (and ask about why it doesn’t work here on StackOverflow) something like this, i.e. includeing a mixin instead of prepending it:
class Foo
def bar
'Hello'
end
end
module FooExtensions
def bar
super + ' World'
end
end
class Foo
include FooExtensions
end
Unfortunately, that won’t work. It’s a good idea, because it uses inheritance, which means that you can use super. However, Module#include inserts the mixin above the class in the inheritance hierarchy, which means that FooExtensions#bar will never be called (and if it were called, the super would not actually refer to Foo#bar but rather to Object#bar which doesn’t exist), since Foo#bar will always be found first.
Method Wrapping
The big question is: how can we hold on to the bar method, without actually keeping around an actual method? The answer lies, as it does so often, in functional programming. We get a hold of the method as an actual object, and we use a closure (i.e. a block) to make sure that we and only we hold on to that object:
class Foo
def bar
'Hello'
end
end
class Foo
old_bar = instance_method(:bar)
define_method(:bar) do
old_bar.bind(self).() + ' World'
end
end
Foo.new.bar # => 'Hello World'
This is very clean: since old_bar is just a local variable, it will go out of scope at the end of the class body, and it is impossible to access it from anywhere, even using reflection! And since Module#define_method takes a block, and blocks close over their surrounding lexical environment (which is why we are using define_method instead of def here), it (and only it) will still have access to old_bar, even after it has gone out of scope.
Short explanation:
old_bar = instance_method(:bar)
Here we are wrapping the bar method into an UnboundMethod method object and assigning it to the local variable old_bar. This means, we now have a way to hold on to bar even after it has been overwritten.
old_bar.bind(self)
This is a bit tricky. Basically, in Ruby (and in pretty much all single-dispatch based OO languages), a method is bound to a specific receiver object, called self in Ruby. In other words: a method always knows what object it was called on, it knows what its self is. But, we grabbed the method directly from a class, how does it know what its self is?
Well, it doesn’t, which is why we need to bind our UnboundMethod to an object first, which will return a Method object that we can then call. (UnboundMethods cannot be called, because they don’t know what to do without knowing their self.)
And what do we bind it to? We simply bind it to ourselves, that way it will behave exactly like the original bar would have!
Lastly, we need to call the Method that is returned from bind. In Ruby 1.9, there is some nifty new syntax for that (.()), but if you are on 1.8, you can simply use the call method; that’s what .() gets translated to anyway.
Here are a couple of other questions, where some of those concepts are explained:
How do I reference a function in Ruby?
Is Ruby’s code block same as C♯’s lambda expression?
“Dirty” Monkey Patching
alias_method chain
The problem we are having with our monkey patching is that when we overwrite the method, the method is gone, so we cannot call it anymore. So, let’s just make a backup copy!
class Foo
def bar
'Hello'
end
end
class Foo
alias_method :old_bar, :bar
def bar
old_bar + ' World'
end
end
Foo.new.bar # => 'Hello World'
Foo.new.old_bar # => 'Hello'
The problem with this is that we have now polluted the namespace with a superfluous old_bar method. This method will show up in our documentation, it will show up in code completion in our IDEs, it will show up during reflection. Also, it still can be called, but presumably we monkey patched it, because we didn’t like its behavior in the first place, so we might not want other people to call it.
Despite the fact that this has some undesirable properties, it has unfortunately become popularized through AciveSupport’s Module#alias_method_chain.
An aside: Refinements
In case you only need the different behavior in a few specific places and not throughout the whole system, you can use Refinements to restrict the monkey patch to a specific scope. I am going to demonstrate it here using the Module#prepend example from above:
class Foo
def bar
'Hello'
end
end
module ExtendedFoo
module FooExtensions
def bar
super + ' World'
end
end
refine Foo do
prepend FooExtensions
end
end
Foo.new.bar # => 'Hello'
# We haven’t activated our Refinement yet!
using ExtendedFoo
# Activate our Refinement
Foo.new.bar # => 'Hello World'
# There it is!
You can see a more sophisticated example of using Refinements in this question: How to enable monkey patch for specific method?
Abandoned ideas
Before the Ruby community settled on Module#prepend, there were multiple different ideas floating around that you may occasionally see referenced in older discussions. All of these are subsumed by Module#prepend.
Method Combinators
One idea was the idea of method combinators from CLOS. This is basically a very lightweight version of a subset of Aspect-Oriented Programming.
Using syntax like
class Foo
def bar:before
# will always run before bar, when bar is called
end
def bar:after
# will always run after bar, when bar is called
# may or may not be able to access and/or change bar’s return value
end
end
you would be able to “hook into” the execution of the bar method.
It is however not quite clear if and how you get access to bar’s return value within bar:after. Maybe we could (ab)use the super keyword?
class Foo
def bar
'Hello'
end
end
class Foo
def bar:after
super + ' World'
end
end
Replacement
The before combinator is equivalent to prepending a mixin with an overriding method that calls super at the very end of the method. Likewise, the after combinator is equivalent to prepending a mixin with an overriding method that calls super at the very beginning of the method.
You can also do stuff before and after calling super, you can call super multiple times, and both retrieve and manipulate super’s return value, making prepend more powerful than method combinators.
class Foo
def bar:before
# will always run before bar, when bar is called
end
end
# is the same as
module BarBefore
def bar
# will always run before bar, when bar is called
super
end
end
class Foo
prepend BarBefore
end
and
class Foo
def bar:after
# will always run after bar, when bar is called
# may or may not be able to access and/or change bar’s return value
end
end
# is the same as
class BarAfter
def bar
original_return_value = super
# will always run after bar, when bar is called
# has access to and can change bar’s return value
end
end
class Foo
prepend BarAfter
end
old keyword
This idea adds a new keyword similar to super, which allows you to call the overwritten method the same way super lets you call the overridden method:
class Foo
def bar
'Hello'
end
end
class Foo
def bar
old + ' World'
end
end
Foo.new.bar # => 'Hello World'
The main problem with this is that it is backwards incompatible: if you have method called old, you will no longer be able to call it!
Replacement
super in an overriding method in a prepended mixin is essentially the same as old in this proposal.
redef keyword
Similar to above, but instead of adding a new keyword for calling the overwritten method and leaving def alone, we add a new keyword for redefining methods. This is backwards compatible, since the syntax currently is illegal anyway:
class Foo
def bar
'Hello'
end
end
class Foo
redef bar
old + ' World'
end
end
Foo.new.bar # => 'Hello World'
Instead of adding two new keywords, we could also redefine the meaning of super inside redef:
class Foo
def bar
'Hello'
end
end
class Foo
redef bar
super + ' World'
end
end
Foo.new.bar # => 'Hello World'
Replacement
redefining a method is equivalent to overriding the method in a prepended mixin. super in the overriding method behaves like super or old in this proposal.
Take a look at aliasing methods, this is kind of renaming the method to a new name.
For more information and a starting point take a look at this replacing methods article (especially the first part).
The Ruby API docs, also provides (a less elaborate) example.
The class that will make override must to be reloaded after class that contains the original method, so require it in the file that will make overrride.

Ruby class methods. Is it getting called on main object?

I have a class that looks like this:
class Test
def self.hello
puts "I say hello"
end
def goodbye
puts 'goodbye'
end
hello
goodbye
end
This is my output:
ruby class_methods.rb
I say hello
class_methods.rb:11:in `<class:Test>': undefined local variable or method `goodbye' for Test:Class (NameError)
from class_methods.rb:1:in `<main>'
What is hello being called on? It looks like it does indeed get called but what is it being called on? I think it's being called on the main object... but why does that make sense? I thought class methods can only be called on the class object itself not a main object?
What is hello being called on?
Whenever there isn't an explicit receiver, the receiver is self. So the call is implicitly:
self.hello
... where self is the class Test, on which you have just defined the self.hello method.
goodbye is not found because it is defined on an instance of class Test, not the class itself, where it's currently called.
def self.hello is a class method
def self.hello
puts "I say hello"
end
hello or Test.hello
#I say hello
def goodbye is a instance method of class of Test
def goodbye
puts 'goodbye'
end
Test.new.goodbye #instance of Test
#goodbye
self defines class methods whereas defining just a method without self will mean that the method is an instance method, therefore, calling goodbye will raise an error because there is no receiver, an instance of the Test class is needed to send that message or call that method.
When ruby parses the class and evaluates the code it can call hello because there is no need to instantiate an object.
You are defining hello as class method whereas goodbye is an instance method.
class Test
def self.hello
puts "I say hello"
end
...
end
This class method since you are calling hello on self, which is Test class, so you can call hello by Test.hello.
...
def goodbye
puts 'goodbye'
end
To call goodbye method, since this is an instance method, you need to create an instance of Test by using Test.new method. Therefore, you need to use Test.new.goodbye to call goodbye method.

Call a function and method with the same name in Ruby

Forgive me for my english.
I am a php programmer and now i want to learn Ruby.
In php if you want to call function "foo" within a class, you simply call foo(), and if you want to call method "foo" you call this->foo().
The question is, is it possible to call function and method with the same name in Ruby?
For example:
def foo
puts "In foo function"
end
class A
def call_foo
foo
#How can i call foo function, not a method?
end
def foo
puts "In foo method"
end
end
a = A.new
a.call_foo #Prints "In foo method"
There is no such thing as a function in Ruby, only methods.
If you define a method at the top-level it is an instance method of Object.
If you define a class without a superclass, it's superclass is Object.
So, your A#foo simply overrides Object#foo. And if it overrides Object#foo, it should respect its contract. You should never need to call Object#foo on an A, if A#foo implements Object#foo's contract correctly (and it should, otherwise it would be a violation of the Liskov Substitution Principle). If you want to reuse Object#foo's implementation within A#foo, you can defer to the superclass implementation using super.
Note: what you want is possible using reflection, but the correct solution would be to fix your design:
def foo
puts "In foo function"
end
class A
def call_foo
self.class.superclass.public_instance_method(:foo).bind(self).()
end
def foo
puts "In foo method"
end
end
a = A.new
a.call_foo #Prints "In foo function"
The foo method outside of your class definition is bound to Object, which is an instance of Class. So to call your method you can do:
> Object.foo­
=> "In foo function"
But as it was pointed out before, you should rather declare this method in an appropiate class.
You can also declare this method as class method with:
class A
def self.foo
puts "In foo class method"
end
end
Now you can call it without creating an A instance:
> A.foo
=> puts "In foo class method"

Calling super from module method

I'm trying to override a method located in a Gem in Ruby/Rails, and I'm struggling with some problems.
My goal is to execute custom code when a method from the Gem is called, but also to keep executing the original code.
I tried to abstract the code into the following script:
module Foo
class << self
def foobar
puts "foo"
end
end
end
module Foo
class << self
def foobar
puts "bar"
super
end
end
end
Foo.foobar
Executing this script gives me this error:
in `foobar': super: no superclass method `foobar' for Foo:Module (NoMethodError)
How should I write the overriding method so I can call super with this exception being raised?
PS: The overriding works just fine if I remove the super, but then the original method isn't called and I don't want that.
You can do what you want like this:
module Foo
class << self
alias_method :original_foobar, :foobar
def foobar
puts "bar"
original_foobar
end
end
end
Calling super looks for the next method in the method lookup chain. The error is telling you exactly what you are doing here: there is foobar method in the method lookup chain for Foo, since it is not inheriting from anything. The code you show in your example is just a redefinition of the Foo module, so having the first Foo does nothing.

When monkey patching an instance method, can you call the overridden method from the new implementation?

Say I am monkey patching a method in a class, how could I call the overridden method from the overriding method? I.e. Something a bit like super
E.g.
class Foo
def bar()
"Hello"
end
end
class Foo
def bar()
super() + " World"
end
end
>> Foo.new.bar == "Hello World"
EDIT: It has been 9 years since I originally wrote this answer, and it deserves some cosmetic surgery to keep it current.
You can see the last version before the edit here.
You can’t call the overwritten method by name or keyword. That’s one of the many reasons why monkey patching should be avoided and inheritance be preferred instead, since obviously you can call the overridden method.
Avoiding Monkey Patching
Inheritance
So, if at all possible, you should prefer something like this:
class Foo
def bar
'Hello'
end
end
class ExtendedFoo < Foo
def bar
super + ' World'
end
end
ExtendedFoo.new.bar # => 'Hello World'
This works, if you control creation of the Foo objects. Just change every place which creates a Foo to instead create an ExtendedFoo. This works even better if you use the Dependency Injection Design Pattern, the Factory Method Design Pattern, the Abstract Factory Design Pattern or something along those lines, because in that case, there is only place you need to change.
Delegation
If you do not control creation of the Foo objects, for example because they are created by a framework that is outside of your control (like ruby-on-rails for example), then you could use the Wrapper Design Pattern:
require 'delegate'
class Foo
def bar
'Hello'
end
end
class WrappedFoo < DelegateClass(Foo)
def initialize(wrapped_foo)
super
end
def bar
super + ' World'
end
end
foo = Foo.new # this is not actually in your code, it comes from somewhere else
wrapped_foo = WrappedFoo.new(foo) # this is under your control
wrapped_foo.bar # => 'Hello World'
Basically, at the boundary of the system, where the Foo object comes into your code, you wrap it into another object, and then use that object instead of the original one everywhere else in your code.
This uses the Object#DelegateClass helper method from the delegate library in the stdlib.
“Clean” Monkey Patching
Module#prepend: Mixin Prepending
The two methods above require changing the system to avoid monkey patching. This section shows the preferred and least invasive method of monkey patching, should changing the system not be an option.
Module#prepend was added to support more or less exactly this use case. Module#prepend does the same thing as Module#include, except it mixes in the mixin directly below the class:
class Foo
def bar
'Hello'
end
end
module FooExtensions
def bar
super + ' World'
end
end
class Foo
prepend FooExtensions
end
Foo.new.bar # => 'Hello World'
Note: I also wrote a little bit about Module#prepend in this question: Ruby module prepend vs derivation
Mixin Inheritance (broken)
I have seen some people try (and ask about why it doesn’t work here on StackOverflow) something like this, i.e. includeing a mixin instead of prepending it:
class Foo
def bar
'Hello'
end
end
module FooExtensions
def bar
super + ' World'
end
end
class Foo
include FooExtensions
end
Unfortunately, that won’t work. It’s a good idea, because it uses inheritance, which means that you can use super. However, Module#include inserts the mixin above the class in the inheritance hierarchy, which means that FooExtensions#bar will never be called (and if it were called, the super would not actually refer to Foo#bar but rather to Object#bar which doesn’t exist), since Foo#bar will always be found first.
Method Wrapping
The big question is: how can we hold on to the bar method, without actually keeping around an actual method? The answer lies, as it does so often, in functional programming. We get a hold of the method as an actual object, and we use a closure (i.e. a block) to make sure that we and only we hold on to that object:
class Foo
def bar
'Hello'
end
end
class Foo
old_bar = instance_method(:bar)
define_method(:bar) do
old_bar.bind(self).() + ' World'
end
end
Foo.new.bar # => 'Hello World'
This is very clean: since old_bar is just a local variable, it will go out of scope at the end of the class body, and it is impossible to access it from anywhere, even using reflection! And since Module#define_method takes a block, and blocks close over their surrounding lexical environment (which is why we are using define_method instead of def here), it (and only it) will still have access to old_bar, even after it has gone out of scope.
Short explanation:
old_bar = instance_method(:bar)
Here we are wrapping the bar method into an UnboundMethod method object and assigning it to the local variable old_bar. This means, we now have a way to hold on to bar even after it has been overwritten.
old_bar.bind(self)
This is a bit tricky. Basically, in Ruby (and in pretty much all single-dispatch based OO languages), a method is bound to a specific receiver object, called self in Ruby. In other words: a method always knows what object it was called on, it knows what its self is. But, we grabbed the method directly from a class, how does it know what its self is?
Well, it doesn’t, which is why we need to bind our UnboundMethod to an object first, which will return a Method object that we can then call. (UnboundMethods cannot be called, because they don’t know what to do without knowing their self.)
And what do we bind it to? We simply bind it to ourselves, that way it will behave exactly like the original bar would have!
Lastly, we need to call the Method that is returned from bind. In Ruby 1.9, there is some nifty new syntax for that (.()), but if you are on 1.8, you can simply use the call method; that’s what .() gets translated to anyway.
Here are a couple of other questions, where some of those concepts are explained:
How do I reference a function in Ruby?
Is Ruby’s code block same as C♯’s lambda expression?
“Dirty” Monkey Patching
alias_method chain
The problem we are having with our monkey patching is that when we overwrite the method, the method is gone, so we cannot call it anymore. So, let’s just make a backup copy!
class Foo
def bar
'Hello'
end
end
class Foo
alias_method :old_bar, :bar
def bar
old_bar + ' World'
end
end
Foo.new.bar # => 'Hello World'
Foo.new.old_bar # => 'Hello'
The problem with this is that we have now polluted the namespace with a superfluous old_bar method. This method will show up in our documentation, it will show up in code completion in our IDEs, it will show up during reflection. Also, it still can be called, but presumably we monkey patched it, because we didn’t like its behavior in the first place, so we might not want other people to call it.
Despite the fact that this has some undesirable properties, it has unfortunately become popularized through AciveSupport’s Module#alias_method_chain.
An aside: Refinements
In case you only need the different behavior in a few specific places and not throughout the whole system, you can use Refinements to restrict the monkey patch to a specific scope. I am going to demonstrate it here using the Module#prepend example from above:
class Foo
def bar
'Hello'
end
end
module ExtendedFoo
module FooExtensions
def bar
super + ' World'
end
end
refine Foo do
prepend FooExtensions
end
end
Foo.new.bar # => 'Hello'
# We haven’t activated our Refinement yet!
using ExtendedFoo
# Activate our Refinement
Foo.new.bar # => 'Hello World'
# There it is!
You can see a more sophisticated example of using Refinements in this question: How to enable monkey patch for specific method?
Abandoned ideas
Before the Ruby community settled on Module#prepend, there were multiple different ideas floating around that you may occasionally see referenced in older discussions. All of these are subsumed by Module#prepend.
Method Combinators
One idea was the idea of method combinators from CLOS. This is basically a very lightweight version of a subset of Aspect-Oriented Programming.
Using syntax like
class Foo
def bar:before
# will always run before bar, when bar is called
end
def bar:after
# will always run after bar, when bar is called
# may or may not be able to access and/or change bar’s return value
end
end
you would be able to “hook into” the execution of the bar method.
It is however not quite clear if and how you get access to bar’s return value within bar:after. Maybe we could (ab)use the super keyword?
class Foo
def bar
'Hello'
end
end
class Foo
def bar:after
super + ' World'
end
end
Replacement
The before combinator is equivalent to prepending a mixin with an overriding method that calls super at the very end of the method. Likewise, the after combinator is equivalent to prepending a mixin with an overriding method that calls super at the very beginning of the method.
You can also do stuff before and after calling super, you can call super multiple times, and both retrieve and manipulate super’s return value, making prepend more powerful than method combinators.
class Foo
def bar:before
# will always run before bar, when bar is called
end
end
# is the same as
module BarBefore
def bar
# will always run before bar, when bar is called
super
end
end
class Foo
prepend BarBefore
end
and
class Foo
def bar:after
# will always run after bar, when bar is called
# may or may not be able to access and/or change bar’s return value
end
end
# is the same as
class BarAfter
def bar
original_return_value = super
# will always run after bar, when bar is called
# has access to and can change bar’s return value
end
end
class Foo
prepend BarAfter
end
old keyword
This idea adds a new keyword similar to super, which allows you to call the overwritten method the same way super lets you call the overridden method:
class Foo
def bar
'Hello'
end
end
class Foo
def bar
old + ' World'
end
end
Foo.new.bar # => 'Hello World'
The main problem with this is that it is backwards incompatible: if you have method called old, you will no longer be able to call it!
Replacement
super in an overriding method in a prepended mixin is essentially the same as old in this proposal.
redef keyword
Similar to above, but instead of adding a new keyword for calling the overwritten method and leaving def alone, we add a new keyword for redefining methods. This is backwards compatible, since the syntax currently is illegal anyway:
class Foo
def bar
'Hello'
end
end
class Foo
redef bar
old + ' World'
end
end
Foo.new.bar # => 'Hello World'
Instead of adding two new keywords, we could also redefine the meaning of super inside redef:
class Foo
def bar
'Hello'
end
end
class Foo
redef bar
super + ' World'
end
end
Foo.new.bar # => 'Hello World'
Replacement
redefining a method is equivalent to overriding the method in a prepended mixin. super in the overriding method behaves like super or old in this proposal.
Take a look at aliasing methods, this is kind of renaming the method to a new name.
For more information and a starting point take a look at this replacing methods article (especially the first part).
The Ruby API docs, also provides (a less elaborate) example.
The class that will make override must to be reloaded after class that contains the original method, so require it in the file that will make overrride.

Resources