-
-
Notifications
You must be signed in to change notification settings - Fork 21.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Callable unbind doesn't actually unbind arguments #76141
Comments
This comment was marked as outdated.
This comment was marked as outdated.
The implementation actively ignores called arguments, which seems to be the intention of godot/core/variant/callable_bind.cpp Line 242 in a7276f1
Usecase for this is connecting to a signal that has some argument This is also documented imo quite clearly:
To achieve this behavior (for callables that are actual named functions) you can do: callable = Callable(callable.get_object(), callable.get_method()).bindv(callable.get_bound_arguments().slice(1)) |
You are right, I think this is a bug. func foo(a: int, b: int, c: int):
prints(a, b, c)
func _ready():
var callable = foo.bind(88, 99)
callable.call(11) # Prints "11 88 99".
callable = callable.unbind(1)
callable.call(22, 33) # Prints "22 88 99". Expected "22 33 99" (or "22 33 88"?). |
I mean I'd say it isn't a bug but does cause confusion sure, also the use here isn't really something that's normal to do? Why would you remove bound arguments, like if you were given a callable from somewhere and don't have control over it |
|
A thing that would be useful though is extraction of the underlying callable, i.e. getting the subject of |
Honestly this was unclear to me, i thought the "extra arguments" it was referring to here were the bound arguments in the callable supplied by a previous
I agree that it's not very useful (outside of esoteric cases), but it's just how i'd expect But if this is the intended behavior then it should really not be named |
The documentation could do with a little clarification, will look into it tomorrow But |
It's funny that I found the correct use of this method in my project (I didn't think about the inconsistency), but in the context of this issue I got confused. Indeed, this is a very unfortunate naming. func _ready() -> void:
_scroll_bar.changed.connect(_update_scroll_bar)
_scroll_bar.value_changed.connect(_update_scroll_bar.unbind(1))
func _update_scroll_bar() -> void:
# ... |
Which other scripting languages use it this way? im trying to look at some other scripting languages but they dont seem to use bind/unbind in this way, if they even have it/something comparable at all. Ruby seems to use bind/unbind to bind a callable to an object/unbind a callable from an object, but nothing for arguments |
My bad I forget where I saw it used before, might have gotten it confused |
I've thought about it a bit, and it seems to me that we can make it consistent. func f(a: int, b: int, c: int) -> void:
prints(a, b, c)
func _ready() -> void:
var g := f.bind(33)
var h := f.bind(22, 33)
# All examples bellow should print "11 22 33".
f.call(11, 22, 33)
g.call(11, 22)
h.call(11)
h.unbind(1).call(11, 22)
h.unbind(2).call(11, 22, 33)
h.unbind(3).call(11, 22, 33, 44)
g.unbind(1).call(11, 22, 33)
g.unbind(2).call(11, 22, 33, 44)
f.unbind(1).call(11, 22, 33, 44)
f.unbind(2).call(11, 22, 33, 44, 55)
f.unbind(3).call(11, 22, 33, 44, 55, 66)
# ...
|
This comment was marked as outdated.
This comment was marked as outdated.
Documentation PR open |
Thinking more about this I think it should be left as is, there are real usecases for keeping it like this, for example:
Solution: my_signal.connect(my_function.bind(1, 2).unbind(1)) This would be impossible otherwise, also a solution would be somewhat convoluted for a usecase that I'm not actually convinced is realistic While I can think of real world situations where you want the current behavior, I can't really think of any situations where the proposed different functionality would be used The only way to achieve the current functionality if we change it would be a really convoluted use of lambdas, which kind of defeats the purpose of having the bind/unbind in the first place as labmdas can achieve their functionality largely |
I'd suggest opening a proposal for changing this behavior as it isn't a bug, and leave this to be closed by the documentation proposal. |
It probably should be my_signal.connect(my_function.unbind(1).bind(1, 2)) |
No that would call it as |
Godot version
4.0.2
System information
Linux 5.10.167-2-MANJARO
Issue description
Calling
unbind
on a callable doesn't actually unbind the arguments. However it makes godot think the arguments are unbound, thus requiring you to call the callable with fewer arguments. But some of the arguments passed along in the call will be ignored, and the original bound arguments are used instead.Steps to reproduce
Run
The printed output is:
Whereas id expect to see something like
Minimal reproduction project
N/A
The text was updated successfully, but these errors were encountered: