2010-04-24 3 views

답변

6

옵션으로 호출 스택 (발신자, 발신자의 발신자 등)에있는 모든 발신자의 컨텍스트에서 코드를 실행할 수있는 binding_of_caller gem이 있습니다. 이것은 better_errors에서 사용 된 것처럼 호출 스택을 검사 할 때 유용합니다 (은 호출 스택상의 어느 위치에서나 수행하십시오) 호출 스택을 검사하는 데 유용합니다.

클래스 의 객체는 코드의 특정 위치에서 실행 컨텍스트를 캡슐화하고 나중에 사용할 수 있도록이 컨텍스트를 유지합니다. 정말 심하게 OOP의 원칙을 위반

내가 언급해야

http://www.ruby-doc.org/core-2.1.4/Binding.html

, 이 기술은, 디버깅, 재미 또는 교육 목적 사용해야합니다.
주로 인해 eval입니다.

이의 물건을 준비하자

require 'binding_of_caller' # I assume, you installed this gem already? 

즉시 (스택에 가장 가까운, 따라서 0) 발신자 인스턴스를 가져옵니다 :

binding.of_caller(0).eval('self') 

을 ...또는 즉시 호출 방법 :

binding.of_caller(0).eval('__method__') 

당신이 호출 스택을 더 얻을 필요가있는 경우, 발신자의 바인딩을 얻기를 위해 0 이외의 번호를 사용합니다.

어색한 해키. 그러나 당신이 정말로 이것을 필요로한다면 — 거기에 가십시오.

1

self과 같은 의미입니까?

irb> class Object 
    .. def test 
    ..  self 
    .. end 
    .. end 
    => nil 
irb> o = Object.new 
    => #<Object:0xb76c5b6c> 
irb> o.test 
    => #<Object:0xb76c5b6c> 
+17

++ 야를 배포 라이브되는 2 ~ 3 일 후에 다음이 코드를 배포 (열을 제거하기 전에 우리 모두가 잘 갈 것입니다 보장 한 방법이다 양식화 된 Z처럼 – Pierreten

+0

나는'test()'내부에서 ir가 단지'self'라고 입력했을 때 얻을 수있는 객체를 얻고 싶습니다. – lulalala

12

쉽게 당신에게 관련 함수를 호출 한 파일 이름과 라인 번호를 알려 것이다

caller.first 

을 통해 관심있는 함수를 호출하는 코드 줄을 볼 수 있습니다. 그런 다음 어떤 객체인지 다시 계산할 수 있습니다.

그러나 인스턴스 메서드 내에서 특정 기능을 호출 한 개체가 많은 것 같습니다. 나는 이것을 알아내는 방법을 알지 못한다. 그러나 캡슐화를 잘못 악화시킨 것 같기 때문에 어쨌든 사용하지 않을 것이다. 최상의에서

+1

정말 좋은 지적입니다, 나는 단지 호출 객체를 전달할 것입니다 아이디어는 호출 객체에 대한 정보를 자동으로 반영하여 메소드에 대한 몇 가지 인수를 단순화하는 것이 었습니다. –

+1

이상적으로는 두 번 이상이면 수퍼 클래스의 메소드 여야하며 self '. – Peter

2

기술 :

1 # phone.rb 
2 class Phone 
3 def caller_id 
4  caller 
5 end 
6 end 
7 
8 class RecklessDriver 
9 def initialize 
10  @phone = Phone.new 
11 end 
12 def dial 
13  @phone.caller_id 
14 end 
15 end 
16 
17 p = Phone.new 
18 p.caller_id.inspect # => ["phone.rb:18:in `<main>'"] 
19 
20 macek = RecklessDriver.new 
22 macek.dial.inspect # => ["phone.rb:13:in `dial'", "phone.rb:22:in `<main>'"] 

참고 : 실증을 위해행 번호.phone.rb:X은 스크립트의 라인 X을 나타냅니다.

phone.rb:13을보세요! 이 dial 방법은 전화를 보냈습니다! phone.rb:22dial 메서드를 사용한 무모한 드라이버를 나타냅니다!

1

베드로 answer 내 회사에서 생산 코드 예제

에 사용되는 우리는 Paranoia gemdeleted_at 컬럼의 맛에 deleted 플래그를 비하했다. 코드를 넣고, 즉 그 모양을 완전히 끝내 우리는 우리가 마이그레이션에게 remoove_column :lessons, :deleted

class Lesson < ActiveRecord::Base 

    def deleted 
    if caller.select { |c| c.match /serialization\.rb/ }.any? 
     # this is Rails object mapping 
     !!deleted_at 
    else 
     raise 'deplicated - deleted was replaced by deleted_at' 
    end 
    end 
end 
관련 문제