# Dynamically assign function in Ray Actor

**URL:** <https://discuss.ray.io/t/dynamically-assign-function-in-ray-actor/12589>\
**Category:** Ray Core\
**Created:** [October 25, 2023, 2:55pm UTC](https://discuss.ray.io/t/dynamically-assign-function-in-ray-actor/12589 "2023-10-25T14:55:28Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Patrick\_S](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ray.io/patrick_s/32/3936_2.png) [@Patrick\_S](https://discuss.ray.io/u/Patrick_S)\
**Post date:** [October 25, 2023, 2:55pm UTC](https://discuss.ray.io/t/dynamically-assign-function-in-ray-actor/12589/1 "2023-10-25T14:55:29Z")

</div>

**How severe does this issue affect your experience of using Ray?**

- Medium: It contributes to significant difficulty to complete my task, but I can work around it.

I am trying to initialize a ray.remote class with a function, as opposed to simply defining it as a method in the class. I have only been able to do this by creating a proxy function in the class which then invokes this function. My guess is that this has something to do with how Ray is hanfing distributing the code, but I’d like to get a better understanding of this limitation.

**Code example**

```auto
from typing import Any
import ray 
import traceback
import time 

@ray.remote
class ActorProxyFunc():
    
    def __init__ (self, func):
        self.func = func
        self.func_no_proxy = func
        
    def func(self):
        print("called func")
        self.func()

def hello():
    print("hello dynamic")

if __name__ == ' __main__':

    a = ActorProxyFunc.remote(hello)
    
    print("Calling the hello function through the func() proxy")
    try:
        ref = a.func.remote()
        ray.get(ref)
    except:
        print(traceback.format_exc())
    
    # This just used so logs are better ordered
    time.sleep(1)
    
    print("Trying to call the hello function directly")
    try:
        ref = a.func_no_proxy.remote()
        ray.get(ref)
    except:
        print(traceback.format_exc())
    finally:
        # Trying to stop ray from blowing up and hanging my terminal session
        del a

```

---

<div class="post-metadata">

**Author:** ![Jules\_Damji](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ray.io/jules_damji/32/4058_2.png) [@Jules\_Damji](https://discuss.ray.io/u/Jules_Damji)\
**Post date:** [October 27, 2023, 5:04pm UTC](https://discuss.ray.io/t/dynamically-assign-function-in-ray-actor/12589/2 "2023-10-27T17:04:51Z")

</div>

@Patrick_S Good question. When actors are created, the driver or script invoking `a=ActorProxyFunc.remote(hello)` registers the pickled Actor with the GCS, which then  
initiates a `actor-creation` request after talking to a Raylet to determine on what node  
this Actor can be scheduled base on its resources. At this point the code is already picked, with  
all its methods. Dynamically adding code would require updating the pickled code with the new method.

cc: @Ruiyang_Wang do you know if that’s possible to dynamically create actor methods?

 ![Screenshot 2023-10-27 at 10.06.19 AM](https://us1.discourse-cdn.com/flex020/uploads/ray/original/2X/6/65da2663d5083eb4bc0b4ef1f33c6c205d4dcce7.png)

---

<div class="post-metadata">

**Author:** ![Patrick\_S](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ray.io/patrick_s/32/3936_2.png) [@Patrick\_S](https://discuss.ray.io/u/Patrick_S)\
**Post date:** [October 27, 2023, 6:45pm UTC](https://discuss.ray.io/t/dynamically-assign-function-in-ray-actor/12589/3 "2023-10-27T18:45:37Z")

</div>

There are 2 methods called, beside what Ray does, with this statement, a=ActorProxyFunc.remote(hello), **new** and **init**. Since my code is only adding the method during **init** that implies that the object is pickled and registered before **init**. In the code below, I take a different approach and add the method during **new** (). If you comment out the whole RayTestDynamicMethod class you will see it runs as expected. If you then comment out everything but that class, you get this error:

```auto
TypeError: RayTestDynamicMethod. __new__ () missing 1 required positional argument: 'funk'

```

which implies that the ray decorator does not pass any arguments into **new** so it fails when parsing or compiling.

```auto
import ray

## Run 1 comment out this class
@ray.remote
class RayTestDynamicMethod():
    
    def __new__ (cls, funk):
        print("Creating a new Person object")
        instance = super(). __new__ (cls)
        setattr(instance, funk. __name__ , funk)
        return instance

## Run 2, Comment out everything below here
class TestDynamicMethod():
    
    def __new__ (cls, funk):
        print("Creating a new Person object")
        instance = super(). __new__ (cls)
        setattr(instance, funk. __name__ , funk)
        return instance
    
def hello():
    print("hello")
    
if __name__ == ' __main__':
    tda = TestDynamicMethod(hello)
    tda.hello()

```
