github.com/xrash/gopher-lua@v0.0.0-20160304065408-e5faab4db06a/README.rst (about) 1 =============================================================================== 2 GopherLua: VM and compiler for Lua in Go. 3 =============================================================================== 4 5 .. image:: https://godoc.org/github.com/yuin/gopher-lua?status.svg 6 :target: http://godoc.org/github.com/yuin/gopher-lua 7 8 .. image:: https://travis-ci.org/yuin/gopher-lua.svg 9 :target: https://travis-ci.org/yuin/gopher-lua 10 11 .. image:: https://coveralls.io/repos/yuin/gopher-lua/badge.svg 12 :target: https://coveralls.io/r/yuin/gopher-lua 13 14 .. image:: https://badges.gitter.im/Join%20Chat.svg 15 :alt: Join the chat at https://gitter.im/yuin/gopher-lua 16 :target: https://gitter.im/yuin/gopher-lua?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge 17 18 | 19 20 GopherLua is a Lua5.1 VM and compiler written in Go. GopherLua has a same goal 21 with Lua: **Be a scripting language with extensible semantics** . It provides 22 Go APIs that allow you to easily embed a scripting language to your Go host 23 programs. 24 25 .. contents:: 26 :depth: 1 27 28 ---------------------------------------------------------------- 29 Design principle 30 ---------------------------------------------------------------- 31 32 - Be a scripting language with extensible semantics. 33 - User-friendly Go API 34 - The stack based API like the one used in the original Lua 35 implementation will cause a performance improvements in GopherLua 36 (It will reduce memory allocations and concrete type <-> interface conversions). 37 GopherLua API is **not** the stack based API. 38 GopherLua give preference to the user-friendliness over the performance. 39 40 ---------------------------------------------------------------- 41 How about performance? 42 ---------------------------------------------------------------- 43 GopherLua is not fast but not too slow, I think. 44 45 There are some benchmarks on the `wiki page <https://github.com/yuin/gopher-lua/wiki/Benchmarks>`_ . 46 47 ---------------------------------------------------------------- 48 Installation 49 ---------------------------------------------------------------- 50 51 .. code-block:: bash 52 53 go get github.com/yuin/gopher-lua 54 55 GopherLua supports >= Go1.4. 56 57 ---------------------------------------------------------------- 58 Usage 59 ---------------------------------------------------------------- 60 GopherLua APIs perform in much the same way as Lua, **but the stack is used only 61 for passing arguments and receiving returned values.** 62 63 GopherLua supports channel operations. See **"Goroutines"** section. 64 65 Import a package. 66 67 .. code-block:: go 68 69 import ( 70 "github.com/yuin/gopher-lua" 71 ) 72 73 Run scripts in the VM. 74 75 .. code-block:: go 76 77 L := lua.NewState() 78 defer L.Close() 79 if err := L.DoString(`print("hello")`); err != nil { 80 panic(err) 81 } 82 83 .. code-block:: go 84 85 L := lua.NewState() 86 defer L.Close() 87 if err := L.DoFile("hello.lua"); err != nil { 88 panic(err) 89 } 90 91 Refer to `Lua Reference Manual <http://www.lua.org/manual/5.1/>`_ and `Go doc <http://godoc.org/github.com/yuin/gopher-lua>`_ for further information. 92 93 Note that elements that are not commented in `Go doc <http://godoc.org/github.com/yuin/gopher-lua>`_ equivalent to `Lua Reference Manual <http://www.lua.org/manual/5.1/>`_ , except GopherLua uses objects instead of Lua stack indices. 94 95 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 96 Data model 97 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 98 All data in a GopherLua program is an ``LValue`` . ``LValue`` is an interface 99 type that has following methods. 100 101 - ``String() string`` 102 - ``Type() LValueType`` 103 104 105 Objects implement an LValue interface are 106 107 ================ ========================= ================== ======================= 108 Type name Go type Type() value Constants 109 ================ ========================= ================== ======================= 110 ``LNilType`` (constants) ``LTNil`` ``LNil`` 111 ``LBool`` (constants) ``LTBool`` ``LTrue``, ``LFalse`` 112 ``LNumber`` float64 ``LTNumber`` ``-`` 113 ``LString`` string ``LTString`` ``-`` 114 ``LFunction`` struct pointer ``LTFunction`` ``-`` 115 ``LUserData`` struct pointer ``LTUserData`` ``-`` 116 ``LState`` struct pointer ``LTThread`` ``-`` 117 ``LTable`` struct pointer ``LTTable`` ``-`` 118 ``LChannel`` chan LValue ``LTChannel`` ``-`` 119 ================ ========================= ================== ======================= 120 121 You can test an object type in Go way(type assertion) or using a ``Type()`` value. 122 123 .. code-block:: go 124 125 lv := L.Get(-1) // get the value at the top of the stack 126 if str, ok := lv.(lua.LString); ok { 127 // lv is LString 128 fmt.Println(string(str)) 129 } 130 if lv.Type() != lua.LTString { 131 panic("string required.") 132 } 133 134 .. code-block:: go 135 136 lv := L.Get(-1) // get the value at the top of the stack 137 if tbl, ok := lv.(*lua.LTable); ok { 138 // lv is LTable 139 fmt.Println(L.ObjLen(tbl)) 140 } 141 142 Note that ``LBool`` , ``LNumber`` , ``LString`` is not a pointer. 143 144 To test ``LNilType`` and ``LBool``, You **must** use pre-defined constants. 145 146 .. code-block:: go 147 148 lv := L.Get(-1) // get the value at the top of the stack 149 150 if lv == LTrue { // correct 151 } 152 153 if bl, ok == lv.(lua.LBool); ok && bool(bl) { // wrong 154 } 155 156 In Lua, both ``nil`` and ``false`` make a condition false. ``LVIsFalse`` and ``LVAsBool`` implement this specification. 157 158 .. code-block:: go 159 160 lv := L.Get(-1) // get the value at the top of the stack 161 if LVIsFalse(lv) { // lv is nil or false 162 } 163 164 if LVAsBool(lv) { // lv is neither nil nor false 165 } 166 167 Objects that based on go structs(``LFunction``. ``LUserData``, ``LTable``) 168 have some public methods and fields. You can use these methods and fields for 169 performance and debugging, but there are some limitations. 170 171 - Metatable does not work. 172 - No error handlings. 173 174 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 175 Callstack & Registry size 176 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 177 Size of the callstack & registry is **fixed** for mainly performance. 178 You can change the default size of the callstack & registry. 179 180 .. code-block:: go 181 182 lua.RegistrySize = 1024 * 20 183 lua.CallStackSize = 1024 184 L := lua.NewState() 185 defer L.Close() 186 187 You can also create an LState object that has the callstack & registry size specified by ``Options`` . 188 189 .. code-block:: go 190 191 L := lua.NewState(lua.Options{ 192 CallStackSize: 120, 193 RegistrySize: 120*20, 194 }) 195 196 An LState object that has been created by ``*LState#NewThread()`` inherits the callstack & registry size from the parent LState object. 197 198 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 199 Miscellaneous lua.NewState options 200 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 201 - **Options.SkipOpenLibs bool(default false)** 202 - By default, GopherLua opens all built-in libraries when new LState is created. 203 - You can skip this behaviour by setting this to ``true`` . 204 - Using the various `OpenXXX(L *LState) int` functions you can open only those libraries that you require, for an example see below. 205 - **Options.IncludeGoStackTrace bool(default false)** 206 - By default, GopherLua does not show Go stack traces when panics occur. 207 - You can get Go stack traces by setting this to ``true`` . 208 209 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 210 API 211 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 212 213 Refer to `Lua Reference Manual <http://www.lua.org/manual/5.1/>`_ and `Go doc(LState methods) <http://godoc.org/github.com/yuin/gopher-lua>`_ for further information. 214 215 +++++++++++++++++++++++++++++++++++++++++ 216 Calling Go from Lua 217 +++++++++++++++++++++++++++++++++++++++++ 218 219 .. code-block:: go 220 221 func Double(L *lua.LState) int { 222 lv := L.ToInt(1) /* get argument */ 223 L.Push(lua.LNumber(lv * 2)) /* push result */ 224 return 1 /* number of results */ 225 } 226 227 func main() { 228 L := lua.NewState() 229 defer L.Close() 230 L.SetGlobal("double", L.NewFunction(Double)) /* Original lua_setglobal uses stack... */ 231 } 232 233 .. code-block:: lua 234 235 print(double(20)) -- > "40" 236 237 Any function registered with GopherLua is a ``lua.LGFunction``, defined in ``value.go`` 238 239 .. code-block:: go 240 241 type LGFunction func(*LState) int 242 243 Working with coroutines. 244 245 .. code-block:: go 246 247 co := L.NewThread() /* create a new thread */ 248 fn := L.GetGlobal("coro").(*lua.LFunction) /* get function from lua */ 249 for { 250 st, err, values := L.Resume(co, fn) 251 if st == lua.ResumeError { 252 fmt.Println("yield break(error)") 253 fmt.Println(err.Error()) 254 break 255 } 256 257 for i, lv := range values { 258 fmt.Printf("%v : %v\n", i, lv) 259 } 260 261 if st == lua.ResumeOK { 262 fmt.Println("yield break(ok)") 263 break 264 } 265 } 266 267 +++++++++++++++++++++++++++++++++++++++++ 268 Opening a subset of builtin modules 269 +++++++++++++++++++++++++++++++++++++++++ 270 271 The following demonstrates how to open a subset of the built-in modules in Lua, say for example to avoid enabling modules with access to local files or system calls. 272 273 main.go 274 275 .. code-block:: go 276 277 func main() { 278 L := lua.NewState(lua.Options{SkipOpenLibs: true}) 279 defer L.Close() 280 for _, pair := range []struct { 281 n string 282 f lua.LGFunction 283 }{ 284 {lua.LoadLibName, lua.OpenPackage}, // Must be first 285 {lua.BaseLibName, lua.OpenBase}, 286 {lua.TabLibName, lua.OpenTable}, 287 } { 288 if err := L.CallByParam(lua.P{ 289 Fn: L.NewFunction(pair.f), 290 NRet: 0, 291 Protect: true, 292 }, lua.LString(pair.n)); err != nil { 293 panic(err) 294 } 295 } 296 if err := L.DoFile("main.lua"); err != nil { 297 panic(err) 298 } 299 } 300 301 +++++++++++++++++++++++++++++++++++++++++ 302 Creating a module by Go 303 +++++++++++++++++++++++++++++++++++++++++ 304 305 mymodule.go 306 307 .. code-block:: go 308 309 package mymodule 310 311 import ( 312 "github.com/yuin/gopher-lua" 313 ) 314 315 func Loader(L *lua.LState) int { 316 // register functions to the table 317 mod := L.SetFuncs(L.NewTable(), exports) 318 // register other stuff 319 L.SetField(mod, "name", lua.LString("value")) 320 321 // returns the module 322 L.Push(mod) 323 return 1 324 } 325 326 var exports = map[string]lua.LGFunction{ 327 "myfunc": myfunc, 328 } 329 330 func myfunc(L *lua.LState) int { 331 return 0 332 } 333 334 mymain.go 335 336 .. code-block:: go 337 338 package main 339 340 import ( 341 "./mymodule" 342 "github.com/yuin/gopher-lua" 343 ) 344 345 func main() { 346 L := lua.NewState() 347 defer L.Close() 348 L.PreloadModule("mymodule", mymodule.Loader) 349 if err := L.DoFile("main.lua"); err != nil { 350 panic(err) 351 } 352 } 353 354 main.lua 355 356 .. code-block:: lua 357 358 local m = require("mymodule") 359 m.myfunc() 360 print(m.name) 361 362 363 +++++++++++++++++++++++++++++++++++++++++ 364 Calling Lua from Go 365 +++++++++++++++++++++++++++++++++++++++++ 366 367 .. code-block:: go 368 369 L := lua.NewState() 370 defer L.Close() 371 if err := L.DoFile("double.lua"); err != nil { 372 panic(err) 373 } 374 if err := L.CallByParam(lua.P{ 375 Fn: L.GetGlobal("double"), 376 NRet: 1, 377 Protect: true, 378 }, lua.LNumber(10)); err != nil { 379 panic(err) 380 } 381 ret := L.Get(-1) // returned value 382 L.Pop(1) // remove received value 383 384 If ``Protect`` is false, GopherLua will panic instead of returning an ``error`` value. 385 386 +++++++++++++++++++++++++++++++++++++++++ 387 User-Defined types 388 +++++++++++++++++++++++++++++++++++++++++ 389 You can extend GopherLua with new types written in Go. 390 ``LUserData`` is provided for this purpose. 391 392 .. code-block:: go 393 394 type Person struct { 395 Name string 396 } 397 398 const luaPersonTypeName = "person" 399 400 // Registers my person type to given L. 401 func registerPersonType(L *lua.LState) { 402 mt := L.NewTypeMetatable(luaPersonTypeName) 403 L.SetGlobal("person", mt) 404 // static attributes 405 L.SetField(mt, "new", L.NewFunction(newPerson)) 406 // methods 407 L.SetField(mt, "__index", L.SetFuncs(L.NewTable(), personMethods)) 408 } 409 410 // Constructor 411 func newPerson(L *lua.LState) int { 412 person := &Person{L.CheckString(1)} 413 ud := L.NewUserData() 414 ud.Value = person 415 L.SetMetatable(ud, L.GetTypeMetatable(luaPersonTypeName)) 416 L.Push(ud) 417 return 1 418 } 419 420 // Checks whether the first lua argument is a *LUserData with *Person and returns this *Person. 421 func checkPerson(L *lua.LState) *Person { 422 ud := L.CheckUserData(1) 423 if v, ok := ud.Value.(*Person); ok { 424 return v 425 } 426 L.ArgError(1, "person expected") 427 return nil 428 } 429 430 var personMethods = map[string]lua.LGFunction{ 431 "name": personGetSetName, 432 } 433 434 // Getter and setter for the Person#Name 435 func personGetSetName(L *lua.LState) int { 436 p := checkPerson(L) 437 if L.GetTop() == 2 { 438 p.Name = L.CheckString(2) 439 return 0 440 } 441 L.Push(lua.LString(p.Name)) 442 return 1 443 } 444 445 func main() { 446 L := lua.NewState() 447 defer L.Close() 448 registerPersonType(L) 449 if err := L.DoString(` 450 p = person.new("Steeve") 451 print(p:name()) -- "Steeve" 452 p:name("Alice") 453 print(p:name()) -- "Alice" 454 `); err != nil { 455 panic(err) 456 } 457 } 458 459 +++++++++++++++++++++++++++++++++++++++++ 460 Goroutines 461 +++++++++++++++++++++++++++++++++++++++++ 462 The ``LState`` is not goroutine-safe. It is recommended to use one LState per goroutine and communicate between goroutines by using channels. 463 464 Channels are represented by ``channel`` objects in GopherLua. And a ``channel`` table provides functions for performing channel operations. 465 466 Some objects can not be sent over channels due to having non-goroutine-safe objects inside itself. 467 468 - a thread(state) 469 - a function 470 - an userdata 471 - a table with a metatable 472 473 You **must not** send these objects from Go APIs to channels. 474 475 476 477 .. code-block:: go 478 479 func receiver(ch, quit chan lua.LValue) { 480 L := lua.NewState() 481 defer L.Close() 482 L.SetGlobal("ch", lua.LChannel(ch)) 483 L.SetGlobal("quit", lua.LChannel(quit)) 484 if err := L.DoString(` 485 local exit = false 486 while not exit do 487 channel.select( 488 {"|<-", ch, function(ok, v) 489 if not ok then 490 print("channel closed") 491 exit = true 492 else 493 print("received:", v) 494 end 495 end}, 496 {"|<-", quit, function(ok, v) 497 print("quit") 498 exit = true 499 end} 500 ) 501 end 502 `); err != nil { 503 panic(err) 504 } 505 } 506 507 func sender(ch, quit chan lua.LValue) { 508 L := lua.NewState() 509 defer L.Close() 510 L.SetGlobal("ch", lua.LChannel(ch)) 511 L.SetGlobal("quit", lua.LChannel(quit)) 512 if err := L.DoString(` 513 ch:send("1") 514 ch:send("2") 515 `); err != nil { 516 panic(err) 517 } 518 ch <- lua.LString("3") 519 quit <- lua.LTrue 520 } 521 522 func main() { 523 ch := make(chan lua.LValue) 524 quit := make(chan lua.LValue) 525 go receiver(ch, quit) 526 go sender(ch, quit) 527 time.Sleep(3 * time.Second) 528 } 529 530 ''''''''''''''' 531 Go API 532 ''''''''''''''' 533 534 ``ToChannel``, ``CheckChannel``, ``OptChannel`` are available. 535 536 Refer to `Go doc(LState methods) <http://godoc.org/github.com/yuin/gopher-lua>`_ for further information. 537 538 ''''''''''''''' 539 Lua API 540 ''''''''''''''' 541 542 - **channel.make([buf:int]) -> ch:channel** 543 - Create new channel that has a buffer size of ``buf``. By default, ``buf`` is 0. 544 545 - **channel.select(case:table [, case:table, case:table ...]) -> {index:int, recv:any, ok}** 546 - Same as the ``select`` statement in Go. It returns the index of the chosen case and, if that 547 case was a receive operation, the value received and a boolean indicating whether the channel has been closed. 548 - ``case`` is a table that outlined below. 549 - receiving: `{"|<-", ch:channel [, handler:func(ok, data:any)]}` 550 - sending: `{"<-|", ch:channel, data:any [, handler:func(data:any)]}` 551 - default: `{"default" [, handler:func()]}` 552 553 ``channel.select`` examples: 554 555 .. code-block:: lua 556 557 local idx, recv, ok = channel.select( 558 {"|<-", ch1}, 559 {"|<-", ch2} 560 ) 561 if not ok then 562 print("closed") 563 elseif idx == 1 then -- received from ch1 564 print(recv) 565 elseif idx == 2 then -- received from ch2 566 print(recv) 567 end 568 569 .. code-block:: lua 570 571 channel.select( 572 {"|<-", ch1, function(ok, data) 573 print(ok, data) 574 end}, 575 {"<-|", ch2, "value", function(data) 576 print(data) 577 end}, 578 {"default", function() 579 print("default action") 580 end} 581 ) 582 583 - **channel:send(data:any)** 584 - Send ``data`` over the channel. 585 - **channel:receive() -> ok:bool, data:any** 586 - Receive some data over the channel. 587 - **channel:close()** 588 - Close the channel. 589 590 '''''''''''''''''''''''''''''' 591 The LState pool pattern 592 '''''''''''''''''''''''''''''' 593 To create per-thread LState instances, You can use the ``sync.Pool`` like mechanism. 594 595 .. code-block:: go 596 597 type lStatePool struct { 598 m sync.Mutex 599 saved []*lua.LState 600 } 601 602 func (pl *lStatePool) Get() *lua.LState { 603 pl.m.Lock() 604 defer pl.m.Unlock() 605 n := len(pl.saved) 606 if n == 0 { 607 return pl.New() 608 } 609 x := pl.saved[n-1] 610 pl.saved = pl.saved[0 : n-1] 611 return x 612 } 613 614 func (pl *lStatePool) New() *lua.LState { 615 L := lua.NewState() 616 // setting the L up here. 617 // load scripts, set global variables, share channels, etc... 618 return L 619 } 620 621 func (pl *lStatePool) Put(L *lua.LState) { 622 pl.m.Lock() 623 defer pl.m.Unlock() 624 pl.saved = append(pl.saved, L) 625 } 626 627 func (pl *lStatePool) Shutdown() { 628 for _, L := range pl.saved { 629 L.Close() 630 } 631 } 632 633 // Global LState pool 634 var luaPool = &lStatePool{ 635 saved: make([]*lua.LState, 0, 4), 636 } 637 638 Now, you can get per-thread LState objects from the ``luaPool`` . 639 640 .. code-block:: go 641 642 func MyWorker() { 643 L := luaPool.Get() 644 defer luaPool.Put(L) 645 /* your code here */ 646 } 647 648 func main() { 649 defer luaPool.Shutdown() 650 go MyWorker() 651 go MyWorker() 652 /* etc... */ 653 } 654 655 656 ---------------------------------------------------------------- 657 Differences between Lua and GopherLua 658 ---------------------------------------------------------------- 659 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 660 Goroutines 661 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 662 663 - GopherLua supports channel operations. 664 - GopherLua has a type named ``channel``. 665 - The ``channel`` table provides functions for performing channel operations. 666 667 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 668 Unsupported functions 669 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 670 671 - ``string.dump`` 672 - ``os.setlocale`` 673 - ``collectgarbage`` 674 - ``lua_Debug.namewhat`` 675 - ``package.loadlib`` 676 - debug hooks 677 678 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 679 Miscellaneous notes 680 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 681 682 - ``file:setvbuf`` does not support a line buffering. 683 - Daylight saving time is not supported. 684 - GopherLua has a function to set an environment variable : ``os.setenv(name, value)`` 685 686 ---------------------------------------------------------------- 687 Standalone interpreter 688 ---------------------------------------------------------------- 689 Lua has an interpreter called ``lua`` . GopherLua has an interpreter called ``glua`` . 690 691 .. code-block:: bash 692 693 go get github.com/yuin/gopher-lua/cmd/glua 694 695 ``glua`` has same options as ``lua`` . 696 697 ---------------------------------------------------------------- 698 How to Contribute 699 ---------------------------------------------------------------- 700 See `Guidlines for contributors <https://github.com/yuin/gopher-lua/tree/master/.github/CONTRIBUTING.md>`_ . 701 702 ---------------------------------------------------------------- 703 Libraries for GopherLua 704 ---------------------------------------------------------------- 705 706 - `gopher-luar <https://github.com/layeh/gopher-luar>`_ : Custom type reflection for gopher-lua 707 - `gluamapper <https://github.com/yuin/gluamapper>`_ : Mapping a Lua table to a Go struct 708 - `gluare <https://github.com/yuin/gluare>`_ : Regular expressions for gopher-lua 709 - `gluahttp <https://github.com/cjoudrey/gluahttp>`_ : HTTP request module for gopher-lua 710 - `gopher-json <https://github.com/layeh/gopher-json>`_ : A simple JSON encoder/decoder for gopher-lua 711 - `gluayaml <https://github.com/kohkimakimoto/gluayaml>`_ : Yaml parser for gopher-lua 712 - `glua-lfs <https://github.com/layeh/gopher-lfs>`_ : Partially implements the luafilesystem module for gopher-lua 713 - `gluaurl <https://github.com/cjoudrey/gluaurl>`_ : A url parser/builder module for gopher-lua 714 715 ---------------------------------------------------------------- 716 Donation 717 ---------------------------------------------------------------- 718 719 BTC: 1NEDSyUmo4SMTDP83JJQSWi1MvQUGGNMZB 720 721 ---------------------------------------------------------------- 722 License 723 ---------------------------------------------------------------- 724 MIT 725 726 ---------------------------------------------------------------- 727 Author 728 ---------------------------------------------------------------- 729 Yusuke Inuzuka