P Method in Ruby Hard to Search For

How can I find a Ruby method dependencies?

You can sort of get this using set_trace_func, but since Ruby is dynamic you would also need test code to call the methods so that the call order is printed.

set_trace_func proc { |event, filename, line, id, binding, klass| puts "#{klass}##{id}" }

In Ruby 2.0, TracePoint is a superior alternative.

p parsed[desc][someKey], in ruby what does p mean?

It's Kernel#p method.

According to the documentation:

p(obj) → obj click to toggle source
p(obj1, obj2, ...) → [obj, ...]
p() → nil

For each object, directly writes obj.inspect followed by a newline to
the program’s standard output.

What is difference between p and pp?

p is used to inspect a variable as a debug aide. It works printing the output of the method #inspect. For example p foo will output the content of foo.inspect.

Sometimes you need to debug complex variables or nested variables. In this case p will output a long line that is hard to understand. Instead, pp will put try to arrange the content of the variable so that it is easier to understand, for example indenting nested arrays or using one line for each instance variable of a complex object. pp does this calling the #pretty_inspect method (the pp library adds #pretty_inspect methods to many classes such as String, Array or Struct).

To remember: p = print, pp = pretty print.

Global methods in Ruby

For runtime Ruby has special object the main.

It's some kind of trick that all code runs in the context of this object.

So when you're typing methods like puts, p and so on, all of them are calling in the context of self object and passing to self object.

And here's the second thing - the access control.
As you probably know, Ruby has keywords like private, protected and public - all of them manage the access of calling methods on object. Ruby is checking this access control only when you're have construction like

<name_of_object>.your_method and self.your_method

So when you're typing

self.p "something"

Ruby will decline this call because the p method is private method.

Ruby: is there a keyword to call a method from within itself (analogous to super)?

You can use Kernel#__method__ that returns the name of the current method as a Symbol. Unlike super it's not a keyword but a regular method so you have to pass it to send method along with required arguments in order to call the method.

Here is what __method__ returns:

obj = Object.new

def obj.foo
p __method__
end

obj.foo
# => :foo

And here is an example of class method that dynamically defines factorial methods:

class Foo
def self.define_fact(method_name)
define_method(method_name) do |n|
n > 0 ? n * send(__method__, n - 1) : 1
end
end
end

f = Foo.new
# puts f.fact(5)
# => undefined method `fact' for #<Foo:0x8ede45c> (NoMethodError)
Foo.define_fact :fact
puts f.fact(5)
# => 120

Without __method__ I can't think of any solution that wouldn't involve some kind of eval that is better to avoid if possible.

Finding out where methods are defined in Ruby/Rails (as opposed to Java)

The Pry gem is designed precisely for this kind of explorative use-case.

Pry is an interactive shell that lets you navigate your way around a program's source-code using shell-like commands such as cd and ls.

You can pull the documentation for any method you encounter and even view the source code, including the native C code in some cases (with the pry-doc plugin). You can even jump directly to the file/line where a particular method is defined with the edit-method command. The show-method and show-doc commands also display the precise location of the method they're acting on.

Watch the railscast screencast for more information.

Here are some examples below:

pry(main)> show-doc OpenStruct#initialize

From: /Users/john/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/ostruct.rb @ line 46:
Number of lines: 11

visibility: private
signature: initialize(hash=?)

Create a new OpenStruct object. The optional hash, if given, will
generate attributes and values. For example.

require 'ostruct'
hash = { "country" => "Australia", :population => 20_000_000 }
data = OpenStruct.new(hash)

p data # -> <OpenStruct country="Australia" population=20000000>

By default, the resulting OpenStruct object will have no attributes.

pry(main)>

You can also look up sourcecode with the show-method command:

pry(main)> show-method OpenStruct#initialize

From: /Users/john/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/ostruct.rb @ line 46:
Number of lines: 9

def initialize(hash=nil)
@table = {}
if hash
for k,v in hash
@table[k.to_sym] = v
new_ostruct_member(k)
end
end
end
pry(main)>

See http://pry.github.com for more information :)

Adding methods when subclassing `Struct`

Why does greeting become a method of the created subclass?

The short answer is: because that's how Struct.new works.

Why would it work that way? Imagine if it didn't. greeting would be added to all Structs and that would be bad.

It's passed to the block as an argument.

This is the "how". The "block" is really you defining a function and passing it into new. The code above is syntax sugar for...

func = Proc.new do |new_class|
p "The new subclass is #{new_class}"
def greeting
"Hello #{name} at #{address}"
end
end

Customer = Struct.new('Customer', :name, :address, &func)

See The Ultimate Guide to Blocks, Procs & Lambdas for more.

Struct.new runs the proc, passing in the name of the new class, but it runs it in a special way. It runs it as if it were the class Struct::Customer. It does this (probably) by calling class_eval to run a proc as if it were defined inside another class.

We can do the same to demonstrate.

class Foo
# Defined inside the Foo class, farewell is a method of Foo.
def farewell
"goodbye"
end
end

# This proc is defined outside the Foo class...
func = Proc.new do
def greeting
"hello"
end
end

# ...but we can run it as if it were.
Foo.class_exec(&func)

dave = Foo.new
p dave.greeting

Many Ruby libraries use this trick, and ones like it.


The block passed to each is also a proc, but each just runs it normally passing in each element of the Enumerable.

However, what you're written is rather odd. This...

[1,2,5].each { |x|
public
def m1 a
a + self
end
}[0].m1 3

Is really this.

nums = [1,2,5].each { |x|
public
def m1(a)
a + self
end
}

nums[0].m1(3)

Which is really this.

[1,2,5].each { |x|
public
def m1(a)
a + self
end
}

1.m1(3)

each returns what it iterated over, so it returns [1,2,5]. nums[0] is 1. So we're calling m1 on an Integer. Why would m1 be defined on an Integer?

It isn't! It's actually defined on Object. Why?

Everything is an object in Ruby, there always has to be a self. When outside a class in Ruby, self is main which is an Object. m1 is a method of Object.

p self         # main
p self.class # Object

Integer inherits from Object so it can call m1. We can see this using method. Everything is an object, including Methods.

p self.method(:m1)  #<Method: Object#m1>
p 1.method(:m1) #<Method: Integer(Object)#m1>

That says m1 is defined on Object and Integer inherits it from Object.

But why is it private? Any method defined like this is defined on Object. (Almost) everything inherits from Object. If it were public, methods in a script would be polluting other classes. So they're private. This is a special case only for main.


Defining m1 in each is a red herring. each is just running the code but doing nothing special. You can just define it in main (ie. Object) and get the same effect.

public
def m1(a)
p a + self
end

p self.method(:m1)
p 1.method(:m1)

In Ruby, is there an Array method that combines 'select' and 'map'?

I usually use map and compact together along with my selection criteria as a postfix if. compact gets rid of the nils.

jruby-1.5.0 > [1,1,1,2,3,4].map{|n| n*3 if n==1}    
=> [3, 3, 3, nil, nil, nil]

jruby-1.5.0 > [1,1,1,2,3,4].map{|n| n*3 if n==1}.compact
=> [3, 3, 3]


Related Topics



Leave a reply



Submit