Detecting the constructor calls & return calls in an expr

74 views
Skip to first unread message

Julia Tylors

unread,
Jan 3, 2016, 6:52:18 PM1/3/16
to julia-users
I am planning to detect the constructor calls and return statement of a function 


a = quote begin
       x = Foo(12)
       y = 5 + 6
       f(x.val,y)
       x.val * y
end

a is an Expr, in this expression , I would like to detect the  constructor calls (Foo(12)(  and distinguish them from normal function calls(fx.val,y).
and i also want to identify the return statement, (x.val*y). How can i do it programmatically?

Thanks

       

Isaiah Norton

unread,
Jan 3, 2016, 9:58:49 PM1/3/16
to julia...@googlegroups.com
There is no AST-level distinction between a "constructor call" and a "normal function call", see [1]. Look at the code in 'reflection.jl' to see how to determine the applicable method for a given name (which may be a constructor). If that doesn't help, it would be helpful to clarify the goal.

For return statements, use `expand(a)` to convert the expression to goto form, which should contain only explicit returns.

Julia Tylors

unread,
Jan 3, 2016, 10:49:12 PM1/3/16
to julia-users
Hi, my end goal is whenever a constructor call is made, I want to detect it and keep track of it by creating an object 

For example 
   f = Foo(12)
  I want to detect this and create a record and save it to a db.

Thanks

Eric Forgy

unread,
Jan 3, 2016, 10:56:45 PM1/3/16
to julia-users
Hi,

Maybe I am missing something, but could you just put the recording code in the constructor itself?

type Foo
    x
::Int

   
function Foo(x)
        record_Foo
()
       
new(x)
   
end
end


Jeffrey Sarnoff

unread,
Jan 3, 2016, 10:59:11 PM1/3/16
to julia-users
Hi Julia,

The simplest way to do this is to make Foo a type and define its type constructor to behave as you wish.

type Foo
    n::Float64
end

function Foo(n::Float64)
   record = createRecordForFooDB(n)
   saveRecordInFooDB(record)
   println("saved Foo($(n)) to DB")
end

Julia Tylors

unread,
Jan 3, 2016, 11:22:10 PM1/3/16
to julia-users
But the you can't be doing this for every new type which is being defined by other programmers.
So I need more general way. For every constructor of every type,
That makes it a bit problematic.
Thanks

Jeffrey Sarnoff

unread,
Jan 3, 2016, 11:24:25 PM1/3/16
to julia-users
Do you want to create DB entries when other programmer's types are called?

Jeffrey Sarnoff

unread,
Jan 3, 2016, 11:28:04 PM1/3/16
to julia-users
Are you trying to instrument all creation of typed instances?

Julia Tylors

unread,
Jan 3, 2016, 11:34:02 PM1/3/16
to julia-users
Yes basically I am trying to instrument all creation of typed instances.
detect an constructor call and record it. for a specific piece of code.
For example

@detect function f(x::Int64)
           y = Foo(x)

end

Jeffrey Sarnoff

unread,
Jan 3, 2016, 11:45:50 PM1/3/16
to julia-users
I have no direct knowledge of that.  Until someone else can give you more specific guidance, take a look at how profiling is done (as that involves the same task):

Tim Holy

unread,
Jan 4, 2016, 12:10:18 AM1/4/16
to julia...@googlegroups.com
You could try looking for :new exprs:

julia> type Foo f::Int end

julia> f() = Foo(12)
f (generic function with 1 method)

julia> @code_typed f()
1-element Array{Any,1}:
:($(Expr(:lambda, Any[], Any[Any[],Any[],Any[],Any[]], :(begin # none, line
1:
return $(Expr(:new, :((top(getfield))(Main,:Foo)::Type{Foo}), 12))
end::Foo))))

Best,
--Tim

Julia Tylors

unread,
Jan 4, 2016, 12:13:05 AM1/4/16
to julia-users
How about we override
Base.call{T}(::Type{T},args...) = ( mystuff; original Base.call; )

Can i do something like this?

Thanks 

On Sunday, January 3, 2016 at 6:58:49 PM UTC-8, Isaiah wrote:

Jeffrey Sarnoff

unread,
Jan 4, 2016, 12:55:30 AM1/4/16
to julia-users
I can get you halfway there:

julia> Base.call{T<:Function}(fn::T, arg::Any) = begin println("I see: ($fn($arg))"); fn(arg) end
call (generic function with 1037 methods)

julia> Base.call{T<:Function}(fn::T, arg1::Any, arg2::Any) = begin println("I see: ($fn($arg1,$arg2))"); fn(arg1,arg2) end
call (generic function with 1038 methods)

julia> call(exp,5.4)
I see: (exp(5.4))
221.40641620418717

julia> call(+,1,2)
I see: (+(1,2))
3

julia> exp(5.4)
221.40641620418717

julia> 1+2
3
Reply all
Reply to author
Forward
0 new messages